first attempt
diff --git a/openstack/networking/v2/extensions/portsbinding/fixtures.go b/openstack/networking/v2/extensions/portsbinding/fixtures.go
new file mode 100644
index 0000000..9f7bd08
--- /dev/null
+++ b/openstack/networking/v2/extensions/portsbinding/fixtures.go
@@ -0,0 +1,206 @@
+package portsbinding
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	fake "github.com/rackspace/gophercloud/openstack/networking/v2/common"
+	th "github.com/rackspace/gophercloud/testhelper"
+)
+
+func HandleListSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/v2.0/ports", 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, `
+{
+    "ports": [
+        {
+            "status": "ACTIVE",
+            "binding:host_id": "devstack",
+            "name": "",
+            "admin_state_up": true,
+            "network_id": "70c1db1f-b701-45bd-96e0-a313ee3430b3",
+            "tenant_id": "",
+            "device_owner": "network:router_gateway",
+            "mac_address": "fa:16:3e:58:42:ed",
+            "fixed_ips": [
+                {
+                    "subnet_id": "008ba151-0b8c-4a67-98b5-0d2b87666062",
+                    "ip_address": "172.24.4.2"
+                }
+            ],
+            "id": "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b",
+            "security_groups": [],
+            "device_id": "9ae135f4-b6e0-4dad-9e91-3c223e385824",
+            "binding:vnic_type": "normal"
+        }
+    ]
+}
+      `)
+	})
+}
+
+func HandleGet(t *testing.T) {
+	th.Mux.HandleFunc("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", 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, `
+{
+    "port": {
+        "status": "ACTIVE",
+        "binding:host_id": "devstack",
+        "name": "",
+        "allowed_address_pairs": [],
+        "admin_state_up": true,
+        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
+        "tenant_id": "7e02058126cc4950b75f9970368ba177",
+        "extra_dhcp_opts": [],
+        "binding:vif_details": {
+            "port_filter": true,
+            "ovs_hybrid_plug": true
+        },
+        "binding:vif_type": "ovs",
+        "device_owner": "network:router_interface",
+        "port_security_enabled": false,
+        "mac_address": "fa:16:3e:23:fd:d7",
+        "binding:profile": {},
+        "binding:vnic_type": "normal",
+        "fixed_ips": [
+            {
+                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
+                "ip_address": "10.0.0.1"
+            }
+        ],
+        "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2",
+        "security_groups": [],
+        "device_id": "5e3898d7-11be-483e-9732-b2f5eccd2b2e"
+    }
+}
+    `)
+	})
+}
+
+func HandleCreate(t *testing.T) {
+	th.Mux.HandleFunc("/v2.0/ports", 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, `
+{
+    "port": {
+        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
+        "name": "private-port",
+        "admin_state_up": true,
+		"fixed_ips": [
+				{
+						"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
+						"ip_address": "10.0.0.2"
+				}
+		],
+		"security_groups": ["foo"],
+		"binding:host_id": "HOST1",
+        "binding:vnic_type": "normal"
+    }
+}
+			`)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusCreated)
+
+		fmt.Fprintf(w, `
+{
+    "port": {
+        "status": "DOWN",
+        "name": "private-port",
+        "allowed_address_pairs": [],
+        "admin_state_up": true,
+        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
+        "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
+        "device_owner": "",
+        "mac_address": "fa:16:3e:c9:cb:f0",
+        "fixed_ips": [
+            {
+                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
+                "ip_address": "10.0.0.2"
+            }
+        ],
+        "binding:host_id": "HOST1",
+        "binding:vnic_type": "normal",
+        "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
+        "security_groups": [
+            "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
+        ],
+        "device_id": ""
+    }
+}
+		`)
+	})
+}
+
+func HandleUpdate(t *testing.T) {
+	th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "PUT")
+		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, `
+{
+		"port": {
+			"name": "new_port_name",
+			"fixed_ips": [
+				{
+					"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
+					"ip_address": "10.0.0.3"
+				}
+			],
+			"security_groups": [
+            	"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
+        	],
+        	"binding:host_id": "HOST1",
+        	"binding:vnic_type": "normal"
+		}
+}
+			`)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+
+		fmt.Fprintf(w, `
+{
+    "port": {
+        "status": "DOWN",
+        "name": "new_port_name",
+        "admin_state_up": true,
+        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
+        "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
+        "device_owner": "",
+        "mac_address": "fa:16:3e:c9:cb:f0",
+        "fixed_ips": [
+            {
+                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
+                "ip_address": "10.0.0.3"
+            }
+        ],
+        "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
+        "security_groups": [
+            "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
+        ],
+        "device_id": "",
+        "binding:host_id": "HOST1",
+        "binding:vnic_type": "normal"
+    }
+}
+		`)
+	})
+}
diff --git a/openstack/networking/v2/extensions/portsbinding/requests.go b/openstack/networking/v2/extensions/portsbinding/requests.go
index 7105a49..4d4300a 100644
--- a/openstack/networking/v2/extensions/portsbinding/requests.go
+++ b/openstack/networking/v2/extensions/portsbinding/requests.go
@@ -5,6 +5,13 @@
 	"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
 )
 
+// Get retrieves a specific port based on its unique ID.
+func Get(c *gophercloud.ServiceClient, id string) GetResult {
+	var res GetResult
+	_, res.Err = c.Get(getURL(c, id), &res.Body, nil)
+	return res
+}
+
 // CreateOpts represents the attributes used when creating a new
 // port with extended attributes.
 type CreateOpts struct {
@@ -22,13 +29,6 @@
 	Profile map[string]string
 }
 
-// Get retrieves a specific port based on its unique ID.
-func Get(c *gophercloud.ServiceClient, id string) GetResult {
-	var res GetResult
-	_, res.Err = c.Get(getURL(c, id), &res.Body, nil)
-	return res
-}
-
 // ToPortCreateMap casts a CreateOpts struct to a map.
 func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
 	p, err := opts.CreateOptsBuilder.ToPortCreateMap()
@@ -68,10 +68,18 @@
 
 // UpdateOpts represents the attributes used when updating an existing port.
 type UpdateOpts struct {
+	// UpdateOptsBuilder is the interface options structs have to satisfy in order
+	// to be used in the main Update operation in this package.
 	ports.UpdateOptsBuilder
-	HostID   string
+	// The ID of the host where the port is allocated
+	HostID string
+	// The virtual network interface card (vNIC) type that is bound to the
+	// neutron port
 	VNICType string
-	Profile  map[string]string
+	// A dictionary that enables the application running on the specified
+	// host to pass and receive virtual network interface (VIF) port-specific
+	// information to the plug-in
+	Profile map[string]string
 }
 
 // ToPortUpdateMap casts an UpdateOpts struct to a map.
diff --git a/openstack/networking/v2/extensions/portsbinding/requests_test.go b/openstack/networking/v2/extensions/portsbinding/requests_test.go
index 87592a6..43a001f 100644
--- a/openstack/networking/v2/extensions/portsbinding/requests_test.go
+++ b/openstack/networking/v2/extensions/portsbinding/requests_test.go
@@ -2,50 +2,68 @@
 
 import (
 	"fmt"
-	"net/http"
 	"testing"
 
 	fake "github.com/rackspace/gophercloud/openstack/networking/v2/common"
 	"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
+	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	HandleListSuccessfully(t)
+
+	count := 0
+
+	ports.List(fake.ServiceClient(), ports.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+		count++
+		actual, err := ExtractPorts(page)
+		th.AssertNoErr(t, err)
+
+		expected := []Port{
+			Port{
+				Port: ports.Port{
+					Status:       "ACTIVE",
+					Name:         "",
+					AdminStateUp: true,
+					NetworkID:    "70c1db1f-b701-45bd-96e0-a313ee3430b3",
+					TenantID:     "",
+					DeviceOwner:  "network:router_gateway",
+					MACAddress:   "fa:16:3e:58:42:ed",
+					FixedIPs: []ports.IP{
+						ports.IP{
+							SubnetID:  "008ba151-0b8c-4a67-98b5-0d2b87666062",
+							IPAddress: "172.24.4.2",
+						},
+					},
+					ID:             "d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b",
+					SecurityGroups: []string{},
+					DeviceID:       "9ae135f4-b6e0-4dad-9e91-3c223e385824",
+				},
+				VNICType: "normal",
+			},
+		}
+
+		fmt.Printf("%#v", actual)
+
+		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("/v2.0/ports/46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2", 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, `
-{
-    "port": {
-        "status": "ACTIVE",
-        "name": "",
-        "admin_state_up": true,
-        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
-        "tenant_id": "7e02058126cc4950b75f9970368ba177",
-        "device_owner": "network:router_interface",
-        "mac_address": "fa:16:3e:23:fd:d7",
-        "fixed_ips": [
-            {
-                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
-                "ip_address": "10.0.0.1"
-            }
-        ],
-        "id": "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2",
-        "security_groups": [],
-        "device_id": "5e3898d7-11be-483e-9732-b2f5eccd2b2e",
-        "binding:host_id": "HOST1",
-        "binding:vnic_type": "normal"
-    }
-}
-			`)
-	})
+	HandleGet(t)
 
 	n, err := Get(fake.ServiceClient(), "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2").Extract()
 	th.AssertNoErr(t, err)
@@ -57,7 +75,7 @@
 	th.AssertEquals(t, n.TenantID, "7e02058126cc4950b75f9970368ba177")
 	th.AssertEquals(t, n.DeviceOwner, "network:router_interface")
 	th.AssertEquals(t, n.MACAddress, "fa:16:3e:23:fd:d7")
-	th.AssertDeepEquals(t, n.FixedIPs, []IP{
+	th.AssertDeepEquals(t, n.FixedIPs, []ports.IP{
 		{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.1"},
 	})
 	th.AssertEquals(t, n.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2")
@@ -71,61 +89,7 @@
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
-	th.Mux.HandleFunc("/v2.0/ports", 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, `
-{
-    "port": {
-        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
-        "name": "private-port",
-        "admin_state_up": true,
-		"fixed_ips": [
-				{
-						"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
-						"ip_address": "10.0.0.2"
-				}
-		],
-		"security_groups": ["foo"],
-		"binding:host_id": "HOST1",
-        "binding:vnic_type": "normal"
-    }
-}
-			`)
-
-		w.Header().Add("Content-Type", "application/json")
-		w.WriteHeader(http.StatusCreated)
-
-		fmt.Fprintf(w, `
-{
-    "port": {
-        "status": "DOWN",
-        "name": "private-port",
-        "allowed_address_pairs": [],
-        "admin_state_up": true,
-        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
-        "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
-        "device_owner": "",
-        "mac_address": "fa:16:3e:c9:cb:f0",
-        "fixed_ips": [
-            {
-                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
-                "ip_address": "10.0.0.2"
-            }
-        ],
-        "binding:host_id": "HOST1",
-        "binding:vnic_type": "normal",
-        "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
-        "security_groups": [
-            "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
-        ],
-        "device_id": ""
-    }
-}
-		`)
-	})
+	HandleCreate(t)
 
 	asu := true
 	options := CreateOpts{
@@ -133,7 +97,7 @@
 			Name:         "private-port",
 			AdminStateUp: &asu,
 			NetworkID:    "a87cc70a-3e15-4acf-8205-9b711a3531b7",
-			FixedIPs: []IP{
+			FixedIPs: []ports.IP{
 				{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
 			},
 			SecurityGroups: []string{"foo"},
@@ -151,7 +115,7 @@
 	th.AssertEquals(t, n.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa")
 	th.AssertEquals(t, n.DeviceOwner, "")
 	th.AssertEquals(t, n.MACAddress, "fa:16:3e:c9:cb:f0")
-	th.AssertDeepEquals(t, n.FixedIPs, []IP{
+	th.AssertDeepEquals(t, n.FixedIPs, []ports.IP{
 		{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
 	})
 	th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d")
@@ -171,65 +135,12 @@
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
-	th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) {
-		th.TestMethod(t, r, "PUT")
-		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, `
-{
-		"port": {
-			"name": "new_port_name",
-			"fixed_ips": [
-				{
-					"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
-					"ip_address": "10.0.0.3"
-				}
-			],
-			"security_groups": [
-            	"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
-        	],
-        	"binding:host_id": "HOST1",
-        	"binding:vnic_type": "normal"
-		}
-}
-			`)
-
-		w.Header().Add("Content-Type", "application/json")
-		w.WriteHeader(http.StatusOK)
-
-		fmt.Fprintf(w, `
-{
-    "port": {
-        "status": "DOWN",
-        "name": "new_port_name",
-        "admin_state_up": true,
-        "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
-        "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
-        "device_owner": "",
-        "mac_address": "fa:16:3e:c9:cb:f0",
-        "fixed_ips": [
-            {
-                "subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
-                "ip_address": "10.0.0.3"
-            }
-        ],
-        "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
-        "security_groups": [
-            "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
-        ],
-        "device_id": "",
-        "binding:host_id": "HOST1",
-        "binding:vnic_type": "normal"
-    }
-}
-		`)
-	})
+	HandleUpdate(t)
 
 	options := UpdateOpts{
 		UpdateOptsBuilder: ports.UpdateOpts{
 			Name: "new_port_name",
-			FixedIPs: []IP{
+			FixedIPs: []ports.IP{
 				{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"},
 			},
 			SecurityGroups: []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"},
@@ -242,7 +153,7 @@
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, s.Name, "new_port_name")
-	th.AssertDeepEquals(t, s.FixedIPs, []IP{
+	th.AssertDeepEquals(t, s.FixedIPs, []ports.IP{
 		{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"},
 	})
 	th.AssertDeepEquals(t, s.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"})
diff --git a/openstack/networking/v2/extensions/portsbinding/results.go b/openstack/networking/v2/extensions/portsbinding/results.go
index 57379eb..7a0d1c3 100644
--- a/openstack/networking/v2/extensions/portsbinding/results.go
+++ b/openstack/networking/v2/extensions/portsbinding/results.go
@@ -3,6 +3,9 @@
 import (
 	"github.com/mitchellh/mapstructure"
 	"github.com/rackspace/gophercloud"
+
+	"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
+	"github.com/rackspace/gophercloud/pagination"
 )
 
 type commonResult struct {
@@ -48,32 +51,14 @@
 // Port represents a Neutron port. See package documentation for a top-level
 // description of what this is.
 type Port struct {
-	// UUID for the port.
-	ID string `mapstructure:"id" json:"id"`
-	// Network that this port is associated with.
-	NetworkID string `mapstructure:"network_id" json:"network_id"`
-	// Human-readable name for the port. Might not be unique.
-	Name string `mapstructure:"name" json:"name"`
-	// Administrative state of port. If false (down), port does not forward packets.
-	AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
-	// Indicates whether network is currently operational. Possible values include
-	// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
-	Status string `mapstructure:"status" json:"status"`
-	// Mac address to use on this port.
-	MACAddress string `mapstructure:"mac_address" json:"mac_address"`
-	// Specifies IP addresses for the port thus associating the port itself with
-	// the subnets where the IP addresses are picked from
-	FixedIPs []IP `mapstructure:"fixed_ips" json:"fixed_ips"`
-	// Owner of network. Only admin users can specify a tenant_id other than its own.
-	TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
-	// Identifies the entity (e.g.: dhcp agent) using this port.
-	DeviceOwner string `mapstructure:"device_owner" json:"device_owner"`
-	// Specifies the IDs of any security groups associated with a port.
-	SecurityGroups []string `mapstructure:"security_groups" json:"security_groups"`
-	// Identifies the device (e.g., virtual server) using this port.
-	DeviceID string `mapstructure:"device_id" json:"device_id"`
+	ports.Port
 	// The ID of the host where the port is allocated
 	HostID string `mapstructure:"binding:host_id" json:"binding:host_id"`
+	// A dictionary that enables the application to pass information about
+	// functions that the Networking API provides.
+	VIFDetails map[string]string `mapstructure:"binding:vif_details" json:"binding:vif_details"`
+	// The VIF type for the port.
+	VIFType string `mapstructure:"binding:vif_type" json:"binding:vif_type"`
 	// The virtual network interface card (vNIC) type that is bound to the
 	// neutron port
 	VNICType string `mapstructure:"binding:vnic_type" json:"binding:vnic_type"`
@@ -82,3 +67,15 @@
 	// information to the plug-in
 	Profile map[string]string `mapstructure:"binding:profile" json:"binding:profile"`
 }
+
+// ExtractPorts accepts a Page struct, specifically a PortPage struct,
+// and extracts the elements into a slice of Port structs. In other words,
+// a generic collection is mapped into a relevant slice.
+func ExtractPorts(page pagination.Page) ([]Port, error) {
+	var resp struct {
+		Ports []Port `mapstructure:"ports" json:"ports"`
+	}
+
+	err := mapstructure.Decode(page.(ports.PortPage).Body, &resp)
+	return resp.Ports, err
+}