Finishing acceptance tests for routers
diff --git a/acceptance/openstack/networking/v2/extensions/layer3_test.go b/acceptance/openstack/networking/v2/extensions/layer3_test.go
index b1679cc..59ae2e5 100644
--- a/acceptance/openstack/networking/v2/extensions/layer3_test.go
+++ b/acceptance/openstack/networking/v2/extensions/layer3_test.go
@@ -6,11 +6,19 @@
 	"testing"
 
 	base "github.com/rackspace/gophercloud/acceptance/openstack/networking/v2"
+	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external"
 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/layer3/routers"
 	"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
+	"github.com/rackspace/gophercloud/openstack/networking/v2/subnets"
+	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
+const (
+	cidr1 = "10.0.0.1/24"
+	cidr2 = "20.0.0.1/24"
+)
+
 func TestRouterCRUD(t *testing.T) {
 	base.Setup(t)
 	defer base.Teardown()
@@ -30,22 +38,29 @@
 	// Get router
 	getRouter(t, routerID)
 
+	// Create new subnet. Note: this subnet will be deleted when networkID is deleted
+	subnetID := createSubnet(t, networkID, cidr2)
+
 	// Add interface
-	addInterface(t, routerID)
+	addInterface(t, routerID, subnetID)
 
 	// Remove interface
-	removeInterface(t, routerID)
+	removeInterface(t, routerID, subnetID)
 
 	// Delete router
 	deleteRouter(t, routerID)
+
+	// Cleanup
+	networks.Delete(base.Client, networkID)
 }
 
 func createNetwork(t *testing.T) string {
 	t.Logf("Creating a network")
 
-	opts := networks.CreateOpts{
-		Name:         "sample_network",
-		AdminStateUp: true,
+	asu := true
+	opts := external.CreateOpts{
+		Parent:   networks.CreateOpts{Name: "sample_network", AdminStateUp: &asu},
+		External: true,
 	}
 	n, err := networks.Create(base.Client, opts).Extract()
 
@@ -55,9 +70,30 @@
 		t.Fatalf("No ID returned when creating a network")
 	}
 
+	createSubnet(t, n.ID, cidr1)
+
+	t.Logf("Network created: ID [%s]", n.ID)
+
 	return n.ID
 }
 
+func createSubnet(t *testing.T, networkID, cidr string) string {
+	t.Logf("Creating a subnet for network %s", networkID)
+
+	s, err := subnets.Create(base.Client, subnets.CreateOpts{
+		NetworkID: networkID,
+		CIDR:      cidr,
+		IPVersion: subnets.IPv4,
+		Name:      "my_subnet",
+	}).Extract()
+
+	th.AssertNoErr(t, err)
+
+	t.Logf("Subnet created: ID [%s]", s.ID)
+
+	return s.ID
+}
+
 func createRouter(t *testing.T, networkID string) string {
 	t.Logf("Creating a router for network %s", networkID)
 
@@ -78,24 +114,65 @@
 		t.Fatalf("No ID returned when creating a router")
 	}
 
+	t.Logf("Router created: ID [%s]", r.ID)
+
 	return r.ID
 }
 
 func listRouters(t *testing.T) {
+	pager := routers.List(base.Client, routers.ListOpts{})
 
+	err := pager.EachPage(func(page pagination.Page) (bool, error) {
+		routerList, err := routers.ExtractRouters(page)
+		th.AssertNoErr(t, err)
+
+		for _, r := range routerList {
+			t.Logf("Listing router: ID [%s] Name [%s] Status [%s] GatewayInfo [%#v]",
+				r.ID, r.Name, r.Status, r.GatewayInfo)
+		}
+
+		return true, nil
+	})
+
+	th.AssertNoErr(t, err)
 }
 
 func updateRouter(t *testing.T, routerID string) {
+	r, err := routers.Update(base.Client, routerID, routers.UpdateOpts{
+		Name: "another_name",
+	}).Extract()
+	th.AssertNoErr(t, err)
+	th.AssertEquals(t, "another_name", r.Name)
 }
 
 func getRouter(t *testing.T, routerID string) {
+	r, err := routers.Get(base.Client, routerID).Extract()
+
+	th.AssertNoErr(t, err)
+
+	t.Logf("Getting router: ID [%s] Name [%s] Status [%s]", r.ID, r.Name, r.Status)
 }
 
-func addInterface(t *testing.T, routerID string) {
+func addInterface(t *testing.T, routerID, subnetID string) {
+	ir, err := routers.AddInterface(base.Client, routerID, routers.InterfaceOpts{SubnetID: subnetID}).Extract()
+
+	th.AssertNoErr(t, err)
+
+	t.Logf("Interface added to router %s: ID [%s] SubnetID [%s] PortID [%s]", routerID, ir.ID, ir.SubnetID, ir.PortID)
 }
 
-func removeInterface(t *testing.T, routerID string) {
+func removeInterface(t *testing.T, routerID, subnetID string) {
+	ir, err := routers.RemoveInterface(base.Client, routerID, routers.InterfaceOpts{SubnetID: subnetID}).Extract()
+
+	th.AssertNoErr(t, err)
+
+	t.Logf("Interface %s removed from %s", ir.ID, routerID)
 }
 
 func deleteRouter(t *testing.T, routerID string) {
+	t.Logf("Deleting router %s", routerID)
+
+	res := routers.Delete(base.Client, routerID)
+
+	th.AssertNoErr(t, res.Err)
 }
diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go
index b7eb42d..d14578c 100755
--- a/openstack/networking/v2/extensions/layer3/routers/results.go
+++ b/openstack/networking/v2/extensions/layer3/routers/results.go
@@ -15,8 +15,8 @@
 }
 
 // Router represents a Neutron router. A router is a logical entity that
-// forwards packets across internal subnets and NATs them on external networks
-// through an appropriate external gateway.
+// forwards packets across internal subnets and NATs (network address
+// translation) them on external networks through an appropriate gateway.
 //
 // A router has an interface for each subnet with which it is associated. By
 // default, the IP address of such interface is the subnet's gateway IP. Also,
@@ -162,7 +162,7 @@
 	TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
 }
 
-// DeleteResult represents the result of interface operations, such as
+// InterfaceResult represents the result of interface operations, such as
 // AddInterface() and RemoveInterface().
 type InterfaceResult struct {
 	gophercloud.CommonResult
diff --git a/openstack/networking/v2/extensions/provider/results_test.go b/openstack/networking/v2/extensions/provider/results_test.go
index f575197..110123a 100644
--- a/openstack/networking/v2/extensions/provider/results_test.go
+++ b/openstack/networking/v2/extensions/provider/results_test.go
@@ -196,7 +196,8 @@
 		`)
 	})
 
-	options := networks.CreateOpts{Name: "sample_network", AdminStateUp: true}
+	iTrue := true
+	options := networks.CreateOpts{Name: "sample_network", AdminStateUp: &iTrue}
 	res := networks.Create(serviceClient(), options)
 	n, err := ExtractCreate(res)
 
@@ -249,8 +250,8 @@
 		`)
 	})
 
-	shared := true
-	options := networks.UpdateOpts{Name: "new_network_name", AdminStateUp: false, Shared: &shared}
+	iTrue, iFalse := true, false
+	options := networks.UpdateOpts{Name: "new_network_name", AdminStateUp: &iFalse, Shared: &iTrue}
 	res := networks.Update(serviceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options)
 	n, err := ExtractUpdate(res)