Resolve conflicts
diff --git a/acceptance/openstack/compute/v2/bootfromvolume_test.go b/acceptance/openstack/compute/v2/bootfromvolume_test.go
index add0e5f..bbecfad 100644
--- a/acceptance/openstack/compute/v2/bootfromvolume_test.go
+++ b/acceptance/openstack/compute/v2/bootfromvolume_test.go
@@ -53,3 +53,64 @@
 	defer servers.Delete(client, server.ID)
 	t.Logf("Deleting server [%s]...", name)
 }
+
+func TestMultiEphemeral(t *testing.T) {
+	client, err := newClient()
+	th.AssertNoErr(t, err)
+
+	if testing.Short() {
+		t.Skip("Skipping test that requires server creation in short mode.")
+	}
+
+	choices, err := ComputeChoicesFromEnv()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	name := tools.RandomString("Gophercloud-", 8)
+	t.Logf("Creating server [%s].", name)
+
+	bd := []bootfromvolume.BlockDevice{
+		bootfromvolume.BlockDevice{
+			BootIndex:           0,
+			UUID:                choices.ImageID,
+			SourceType:          bootfromvolume.Image,
+			DestinationType:     "local",
+			DeleteOnTermination: true,
+		},
+		bootfromvolume.BlockDevice{
+			BootIndex:           -1,
+			SourceType:          bootfromvolume.Blank,
+			DestinationType:     "local",
+			DeleteOnTermination: true,
+			GuestFormat:         "ext4",
+			VolumeSize:          1,
+		},
+		bootfromvolume.BlockDevice{
+			BootIndex:           -1,
+			SourceType:          bootfromvolume.Blank,
+			DestinationType:     "local",
+			DeleteOnTermination: true,
+			GuestFormat:         "ext4",
+			VolumeSize:          1,
+		},
+	}
+
+	serverCreateOpts := servers.CreateOpts{
+		Name:      name,
+		FlavorRef: choices.FlavorID,
+		ImageRef:  choices.ImageID,
+	}
+	server, err := bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{
+		serverCreateOpts,
+		bd,
+	}).Extract()
+	th.AssertNoErr(t, err)
+	if err = waitForStatus(client, server, "ACTIVE"); err != nil {
+		t.Fatal(err)
+	}
+
+	t.Logf("Created server: %+v\n", server)
+	defer servers.Delete(client, server.ID)
+	t.Logf("Deleting server [%s]...", name)
+}
diff --git a/acceptance/openstack/networking/v2/port_test.go b/acceptance/openstack/networking/v2/port_test.go
index 03e8e27..91bf5bd 100644
--- a/acceptance/openstack/networking/v2/port_test.go
+++ b/acceptance/openstack/networking/v2/port_test.go
@@ -45,10 +45,20 @@
 	th.AssertEquals(t, p.ID, portID)
 
 	// Update port
-	p, err = ports.Update(Client, portID, ports.UpdateOpts{Name: "new_port_name"}).Extract()
+	updateOpts := ports.UpdateOpts{
+		Name: "new_port_name",
+		AllowedAddressPairs: []ports.AddressPair{
+			ports.AddressPair{IPAddress: "192.168.199.201"},
+		},
+	}
+	p, err = ports.Update(Client, portID, updateOpts).Extract()
+
 	th.AssertNoErr(t, err)
 	th.AssertEquals(t, p.Name, "new_port_name")
 
+	updatedPort, err := ports.Get(Client, portID).Extract()
+	th.AssertEquals(t, updatedPort.AllowedAddressPairs[0].IPAddress, "192.168.199.201")
+
 	// Delete port
 	res := ports.Delete(Client, portID)
 	th.AssertNoErr(t, res.Err)
@@ -82,8 +92,8 @@
 		th.AssertNoErr(t, err)
 
 		for _, p := range portList {
-			t.Logf("Port: ID [%s] Name [%s] Status [%s] MAC addr [%s] Fixed IPs [%#v] Security groups [%#v]",
-				p.ID, p.Name, p.Status, p.MACAddress, p.FixedIPs, p.SecurityGroups)
+			t.Logf("Port: ID [%s] Name [%s] Status [%s] MAC addr [%s] Fixed IPs [%#v] Security groups [%#v] Allowed Address Pairs [%#v]",
+				p.ID, p.Name, p.Status, p.MACAddress, p.FixedIPs, p.SecurityGroups, p.AllowedAddressPairs)
 		}
 
 		return true, nil
@@ -108,6 +118,9 @@
 		IPVersion:  subnets.IPv4,
 		Name:       "my_subnet",
 		EnableDHCP: subnets.Down,
+		AllocationPools: []subnets.AllocationPool{
+			subnets.AllocationPool{Start: "192.168.199.2", End: "192.168.199.200"},
+		},
 	}).Extract()
 	return s.ID, err
 }
diff --git a/openstack/client.go b/openstack/client.go
index 33602a6..baa4cb5 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -3,6 +3,7 @@
 import (
 	"fmt"
 	"net/url"
+	"strings"
 
 	"github.com/rackspace/gophercloud"
 	tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens"
@@ -64,8 +65,8 @@
 // Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint.
 func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
 	versions := []*utils.Version{
-		&utils.Version{ID: v20, Priority: 20, Suffix: "/v2.0/"},
-		&utils.Version{ID: v30, Priority: 30, Suffix: "/v3/"},
+		{ID: v20, Priority: 20, Suffix: "/v2.0/"},
+		{ID: v30, Priority: 30, Suffix: "/v3/"},
 	}
 
 	chosen, endpoint, err := utils.ChooseVersion(client, versions)
@@ -110,7 +111,7 @@
 	if options.AllowReauth {
 		client.ReauthFunc = func() error {
 			client.TokenID = ""
-			return AuthenticateV2(client, options)
+			return v2auth(client, endpoint, options)
 		}
 	}
 	client.TokenID = token.ID
@@ -168,7 +169,7 @@
 	if options.AllowReauth {
 		client.ReauthFunc = func() error {
 			client.TokenID = ""
-			return AuthenticateV3(client, options)
+			return v3auth(client, endpoint, options)
 		}
 	}
 	client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
@@ -198,6 +199,40 @@
 	}
 }
 
+func NewIdentityAdminV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
+	eo.ApplyDefaults("identity")
+	eo.Availability = gophercloud.AvailabilityAdmin
+
+	url, err := client.EndpointLocator(eo)
+	if err != nil {
+		return nil, err
+	}
+
+	// Force using v2 API
+	if strings.Contains(url, "/v3") {
+		url = strings.Replace(url, "/v3", "/v2.0", -1)
+	}
+
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
+}
+
+func NewIdentityAdminV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
+	eo.ApplyDefaults("identity")
+	eo.Availability = gophercloud.AvailabilityAdmin
+
+	url, err := client.EndpointLocator(eo)
+	if err != nil {
+		return nil, err
+	}
+
+	// Force using v3 API
+	if strings.Contains(url, "/v2.0") {
+		url = strings.Replace(url, "/v2.0", "/v3", -1)
+	}
+
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
+}
+
 // NewObjectStorageV1 creates a ServiceClient that may be used with the v1 object storage package.
 func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
 	eo.ApplyDefaults("object-store")
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests.go b/openstack/compute/v2/extensions/bootfromvolume/requests.go
index c8edee0..dceff3d 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests.go
@@ -15,6 +15,7 @@
 	Volume   SourceType = "volume"
 	Snapshot SourceType = "snapshot"
 	Image    SourceType = "image"
+	Blank    SourceType = "blank"
 )
 
 // BlockDevice is a structure with options for booting a server instance
@@ -32,6 +33,9 @@
 	// and "local".
 	DestinationType string `json:"destination_type"`
 
+	// GuestFormat [optional] specifies the format of the block device.
+	GuestFormat string `json:"guest_format"`
+
 	// SourceType [required] must be one of: "volume", "snapshot", "image".
 	SourceType SourceType `json:"source_type"`
 
@@ -82,6 +86,9 @@
 		if bd.DestinationType != "" {
 			blockDevice[i]["destination_type"] = bd.DestinationType
 		}
+		if bd.GuestFormat != "" {
+			blockDevice[i]["guest_format"] = bd.GuestFormat
+		}
 
 	}
 	serverMap["block_device_mapping_v2"] = blockDevice
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
index 8a7fa74..2c8bf49 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
@@ -32,8 +32,8 @@
         "name": "createdserver",
         "imageRef": "asdfasdfasdf",
         "flavorRef": "performance1-1",
-	"flavorName": "",
-	"imageName": "",
+        "flavorName": "",
+        "imageName": "",
         "block_device_mapping_v2":[
           {
             "uuid":"123456",
@@ -51,3 +51,81 @@
 	th.AssertNoErr(t, err)
 	th.CheckJSONEquals(t, expected, actual)
 }
+
+func TestCreateMultiEphemeralOpts(t *testing.T) {
+	base := servers.CreateOpts{
+		Name:      "createdserver",
+		ImageRef:  "asdfasdfasdf",
+		FlavorRef: "performance1-1",
+	}
+
+	ext := CreateOptsExt{
+		CreateOptsBuilder: base,
+		BlockDevice: []BlockDevice{
+			BlockDevice{
+				BootIndex:           0,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				SourceType:          Image,
+				UUID:                "123456",
+			},
+			BlockDevice{
+				BootIndex:           -1,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				GuestFormat:         "ext4",
+				SourceType:          Blank,
+				VolumeSize:          1,
+			},
+			BlockDevice{
+				BootIndex:           -1,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				GuestFormat:         "ext4",
+				SourceType:          Blank,
+				VolumeSize:          1,
+			},
+		},
+	}
+
+	expected := `
+    {
+      "server": {
+        "name": "createdserver",
+        "imageRef": "asdfasdfasdf",
+        "flavorRef": "performance1-1",
+        "flavorName": "",
+        "imageName": "",
+        "block_device_mapping_v2":[
+          {
+            "boot_index": "0",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "source_type":"image",
+            "uuid":"123456",
+            "volume_size": "0"
+          },
+          {
+            "boot_index": "-1",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "guest_format":"ext4",
+            "source_type":"blank",
+            "volume_size": "1"
+          },
+          {
+            "boot_index": "-1",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "guest_format":"ext4",
+            "source_type":"blank",
+            "volume_size": "1"
+          }
+        ]
+      }
+    }
+  `
+	actual, err := ext.ToServerCreateMap()
+	th.AssertNoErr(t, err)
+	th.CheckJSONEquals(t, expected, actual)
+}
diff --git a/openstack/compute/v2/servers/fixtures.go b/openstack/compute/v2/servers/fixtures.go
index 4339a16..151fea2 100644
--- a/openstack/compute/v2/servers/fixtures.go
+++ b/openstack/compute/v2/servers/fixtures.go
@@ -399,6 +399,18 @@
 	})
 }
 
+// HandleAdminPasswordChangeSuccessfully sets up the test server to respond to a server password
+// change request.
+func HandleServerForceDeletionSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/asdfasdfasdf/action", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		th.TestJSONRequest(t, r, `{ "forceDelete": "" }`)
+
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
+
 // HandleServerGetSuccessfully sets up the test server to respond to a server Get request.
 func HandleServerGetSuccessfully(t *testing.T) {
 	th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) {
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index f9839d9..8e60daa 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -303,6 +303,17 @@
 	return res
 }
 
+func ForceDelete(client *gophercloud.ServiceClient, id string) ActionResult {
+	var req struct {
+		ForceDelete string `json:"forceDelete"`
+	}
+
+	var res ActionResult
+	_, res.Err = client.Post(actionURL(client, id), req, nil, nil)
+	return res
+
+}
+
 // Get requests details on a single server, by ID.
 func Get(client *gophercloud.ServiceClient, id string) GetResult {
 	var result GetResult
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 88cb54d..e042074 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -78,6 +78,15 @@
 	th.AssertNoErr(t, res.Err)
 }
 
+func TestForceDeleteServer(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleServerForceDeletionSuccessfully(t)
+
+	res := ForceDelete(client.ServiceClient(), "asdfasdfasdf")
+	th.AssertNoErr(t, res.Err)
+}
+
 func TestGetServer(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
diff --git a/openstack/db/v1/configurations/results.go b/openstack/db/v1/configurations/results.go
index 37a77ad..d0d1d6e 100644
--- a/openstack/db/v1/configurations/results.go
+++ b/openstack/db/v1/configurations/results.go
@@ -1,6 +1,8 @@
 package configurations
 
 import (
+	"fmt"
+	"reflect"
 	"time"
 
 	"github.com/mitchellh/mapstructure"
@@ -43,12 +45,18 @@
 		Configs []Config `mapstructure:"configurations" json:"configurations"`
 	}
 
-	err := mapstructure.Decode(casted, &resp)
+	if err := mapstructure.Decode(casted, &resp); err != nil {
+		return nil, err
+	}
 
 	var vals []interface{}
-	switch (casted).(type) {
-	case interface{}:
+	switch casted.(type) {
+	case map[string]interface{}:
 		vals = casted.(map[string]interface{})["configurations"].([]interface{})
+	case map[string][]interface{}:
+		vals = casted.(map[string][]interface{})["configurations"]
+	default:
+		return resp.Configs, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
 	}
 
 	for i, v := range vals {
@@ -71,7 +79,7 @@
 		}
 	}
 
-	return resp.Configs, err
+	return resp.Configs, nil
 }
 
 type commonResult struct {
diff --git a/openstack/db/v1/instances/results.go b/openstack/db/v1/instances/results.go
index 9a49510..95aed16 100644
--- a/openstack/db/v1/instances/results.go
+++ b/openstack/db/v1/instances/results.go
@@ -1,6 +1,8 @@
 package instances
 
 import (
+	"fmt"
+	"reflect"
 	"time"
 
 	"github.com/mitchellh/mapstructure"
@@ -142,16 +144,22 @@
 func ExtractInstances(page pagination.Page) ([]Instance, error) {
 	casted := page.(InstancePage).Body
 
-	var response struct {
+	var resp struct {
 		Instances []Instance `mapstructure:"instances"`
 	}
 
-	err := mapstructure.Decode(casted, &response)
+	if err := mapstructure.Decode(casted, &resp); err != nil {
+		return nil, err
+	}
 
 	var vals []interface{}
-	switch (casted).(type) {
-	case interface{}:
+	switch casted.(type) {
+	case map[string]interface{}:
 		vals = casted.(map[string]interface{})["instances"].([]interface{})
+	case map[string][]interface{}:
+		vals = casted.(map[string][]interface{})["instances"]
+	default:
+		return resp.Instances, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
 	}
 
 	for i, v := range vals {
@@ -160,21 +168,21 @@
 		if t, ok := val["created"].(string); ok && t != "" {
 			creationTime, err := time.Parse(time.RFC3339, t)
 			if err != nil {
-				return response.Instances, err
+				return resp.Instances, err
 			}
-			response.Instances[i].Created = creationTime
+			resp.Instances[i].Created = creationTime
 		}
 
 		if t, ok := val["updated"].(string); ok && t != "" {
 			updatedTime, err := time.Parse(time.RFC3339, t)
 			if err != nil {
-				return response.Instances, err
+				return resp.Instances, err
 			}
-			response.Instances[i].Updated = updatedTime
+			resp.Instances[i].Updated = updatedTime
 		}
 	}
 
-	return response.Instances, err
+	return resp.Instances, nil
 }
 
 // UserRootResult represents the result of an operation to enable the root user.
diff --git a/openstack/identity/v3/tokens/requests.go b/openstack/identity/v3/tokens/requests.go
index d449ca3..d63b1bb 100644
--- a/openstack/identity/v3/tokens/requests.go
+++ b/openstack/identity/v3/tokens/requests.go
@@ -15,9 +15,9 @@
 }
 
 func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
-	h := c.AuthenticatedHeaders()
-	h["X-Subject-Token"] = subjectToken
-	return h
+	return map[string]string{
+		"X-Subject-Token": subjectToken,
+	}
 }
 
 // Create authenticates and either generates a new token, or changes the Scope of an existing token.
diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go
index ddd2bbc..ed0ea07 100644
--- a/openstack/networking/v2/extensions/layer3/routers/requests.go
+++ b/openstack/networking/v2/extensions/layer3/routers/requests.go
@@ -16,6 +16,7 @@
 	ID           string `q:"id"`
 	Name         string `q:"name"`
 	AdminStateUp *bool  `q:"admin_state_up"`
+	Distributed  *bool  `q:"distributed"`
 	Status       string `q:"status"`
 	TenantID     string `q:"tenant_id"`
 	Limit        int    `q:"limit"`
@@ -46,6 +47,7 @@
 type CreateOpts struct {
 	Name         string
 	AdminStateUp *bool
+	Distributed  *bool
 	TenantID     string
 	DriverOpts   map[string]string
 	GatewayInfo  *GatewayInfo
@@ -75,6 +77,10 @@
 		routerMap["admin_state_up"] = opts.AdminStateUp
 	}
 
+	if opts.Distributed != nil {
+		routerMap["distributed"] = opts.Distributed
+	}
+
 	if gophercloud.MaybeString(opts.TenantID) != nil {
 		routerMap["tenant_id"] = opts.TenantID
 	}
@@ -107,6 +113,7 @@
 type UpdateOpts struct {
 	Name         string
 	AdminStateUp *bool
+	Distributed  *bool
 	GatewayInfo  *GatewayInfo
 	Routes       []Route
 }
@@ -120,6 +127,7 @@
 	type router struct {
 		Name         *string      `json:"name,omitempty"`
 		AdminStateUp *bool        `json:"admin_state_up,omitempty"`
+		Distributed  *bool        `json:"distributed,omitempty"`
 		GatewayInfo  *GatewayInfo `json:"external_gateway_info,omitempty"`
 		Routes       []Route      `json:"routes"`
 	}
@@ -131,6 +139,7 @@
 	reqBody := request{Router: router{
 		Name:         gophercloud.MaybeString(opts.Name),
 		AdminStateUp: opts.AdminStateUp,
+		Distributed:  opts.Distributed,
 	}}
 
 	if opts.GatewayInfo != nil {
diff --git a/openstack/networking/v2/extensions/layer3/routers/requests_test.go b/openstack/networking/v2/extensions/layer3/routers/requests_test.go
index 1981733..dbdc6fa 100644
--- a/openstack/networking/v2/extensions/layer3/routers/requests_test.go
+++ b/openstack/networking/v2/extensions/layer3/routers/requests_test.go
@@ -37,6 +37,7 @@
             "name": "second_routers",
             "admin_state_up": true,
             "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3",
+            "distributed": false,
             "id": "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b"
         },
         {
@@ -47,6 +48,7 @@
             "name": "router1",
             "admin_state_up": true,
             "tenant_id": "33a40233088643acb66ff6eb0ebea679",
+            "distributed": false,
             "id": "a9254bdb-2613-4a13-ac4c-adc581fba50d"
         }
     ]
@@ -69,6 +71,7 @@
 				Status:       "ACTIVE",
 				GatewayInfo:  GatewayInfo{NetworkID: ""},
 				AdminStateUp: true,
+				Distributed:  false,
 				Name:         "second_routers",
 				ID:           "7177abc4-5ae9-4bb7-b0d4-89e94a4abf3b",
 				TenantID:     "6b96ff0cb17a4b859e1e575d221683d3",
@@ -77,6 +80,7 @@
 				Status:       "ACTIVE",
 				GatewayInfo:  GatewayInfo{NetworkID: "3c5bcddd-6af9-4e6b-9c3e-c153e521cab8"},
 				AdminStateUp: true,
+				Distributed:  false,
 				Name:         "router1",
 				ID:           "a9254bdb-2613-4a13-ac4c-adc581fba50d",
 				TenantID:     "33a40233088643acb66ff6eb0ebea679",
@@ -127,6 +131,7 @@
         "name": "foo_router",
         "admin_state_up": false,
         "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3",
+        "distributed": false,
         "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e"
     }
 }
@@ -176,6 +181,7 @@
         "name": "router1",
         "admin_state_up": true,
         "tenant_id": "d6554fe62e2f41efbb6e026fad5c1542",
+        "distributed": false,
         "id": "a07eea83-7710-4860-931b-5fe220fae533"
     }
 }
@@ -233,6 +239,7 @@
         "name": "new_name",
         "admin_state_up": true,
         "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3",
+        "distributed": false,
         "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e",
         "routes": [
             {
@@ -287,6 +294,7 @@
         "name": "name",
         "admin_state_up": true,
         "tenant_id": "6b96ff0cb17a4b859e1e575d221683d3",
+        "distributed": false,
         "id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e",
         "routes": []
     }
diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go
index b65a8bc..9b811cb 100644
--- a/openstack/networking/v2/extensions/layer3/routers/results.go
+++ b/openstack/networking/v2/extensions/layer3/routers/results.go
@@ -35,6 +35,9 @@
 	// Administrative state of the router.
 	AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
 
+	// Whether router is disitrubted or not..
+	Distributed bool `json:"distributed" mapstructure:"distributed"`
+
 	// Human readable name for the router. Does not have to be unique.
 	Name string `json:"name" mapstructure:"name"`
 
diff --git a/openstack/networking/v2/ports/requests.go b/openstack/networking/v2/ports/requests.go
index 2caf1ca..e73e10a 100644
--- a/openstack/networking/v2/ports/requests.go
+++ b/openstack/networking/v2/ports/requests.go
@@ -95,15 +95,16 @@
 
 // CreateOpts represents the attributes used when creating a new port.
 type CreateOpts struct {
-	NetworkID      string
-	Name           string
-	AdminStateUp   *bool
-	MACAddress     string
-	FixedIPs       interface{}
-	DeviceID       string
-	DeviceOwner    string
-	TenantID       string
-	SecurityGroups []string
+	NetworkID           string
+	Name                string
+	AdminStateUp        *bool
+	MACAddress          string
+	FixedIPs            interface{}
+	DeviceID            string
+	DeviceOwner         string
+	TenantID            string
+	SecurityGroups      []string
+	AllowedAddressPairs []AddressPair
 }
 
 // ToPortCreateMap casts a CreateOpts struct to a map.
@@ -139,6 +140,9 @@
 	if opts.MACAddress != "" {
 		p["mac_address"] = opts.MACAddress
 	}
+	if opts.AllowedAddressPairs != nil {
+		p["allowed_address_pairs"] = opts.AllowedAddressPairs
+	}
 
 	return map[string]interface{}{"port": p}, nil
 }
@@ -168,12 +172,13 @@
 
 // UpdateOpts represents the attributes used when updating an existing port.
 type UpdateOpts struct {
-	Name           string
-	AdminStateUp   *bool
-	FixedIPs       interface{}
-	DeviceID       string
-	DeviceOwner    string
-	SecurityGroups []string
+	Name                string
+	AdminStateUp        *bool
+	FixedIPs            interface{}
+	DeviceID            string
+	DeviceOwner         string
+	SecurityGroups      []string
+	AllowedAddressPairs []AddressPair
 }
 
 // ToPortUpdateMap casts an UpdateOpts struct to a map.
@@ -198,6 +203,9 @@
 	if opts.Name != "" {
 		p["name"] = opts.Name
 	}
+	if opts.AllowedAddressPairs != nil {
+		p["allowed_address_pairs"] = opts.AllowedAddressPairs
+	}
 
 	return map[string]interface{}{"port": p}, nil
 }
diff --git a/openstack/networking/v2/ports/requests_test.go b/openstack/networking/v2/ports/requests_test.go
index 9e323ef..b442996 100644
--- a/openstack/networking/v2/ports/requests_test.go
+++ b/openstack/networking/v2/ports/requests_test.go
@@ -164,7 +164,13 @@
 								"ip_address": "10.0.0.2"
 						}
 				],
-				"security_groups": ["foo"]
+				"security_groups": ["foo"],
+        "allowed_address_pairs": [
+          {
+            "ip_address": "10.0.0.4",
+            "mac_address": "fa:16:3e:c9:cb:f0"
+          }
+        ]
     }
 }
 			`)
@@ -177,7 +183,6 @@
     "port": {
         "status": "DOWN",
         "name": "private-port",
-        "allowed_address_pairs": [],
         "admin_state_up": true,
         "network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
         "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
@@ -193,6 +198,12 @@
         "security_groups": [
             "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
         ],
+        "allowed_address_pairs": [
+          {
+            "ip_address": "10.0.0.4",
+            "mac_address": "fa:16:3e:c9:cb:f0"
+          }
+        ],
         "device_id": ""
     }
 }
@@ -208,6 +219,9 @@
 			IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
 		},
 		SecurityGroups: []string{"foo"},
+		AllowedAddressPairs: []AddressPair{
+			AddressPair{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
+		},
 	}
 	n, err := Create(fake.ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
@@ -224,6 +238,9 @@
 	})
 	th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d")
 	th.AssertDeepEquals(t, n.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"})
+	th.AssertDeepEquals(t, n.AllowedAddressPairs, []AddressPair{
+		AddressPair{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
+	})
 }
 
 func TestRequiredCreateOpts(t *testing.T) {
@@ -252,6 +269,12 @@
                 "ip_address": "10.0.0.3"
             }
         ],
+        "allowed_address_pairs": [
+          {
+            "ip_address": "10.0.0.4",
+            "mac_address": "fa:16:3e:c9:cb:f0"
+          }
+        ],
 				"security_groups": [
             "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
         ]
@@ -278,6 +301,12 @@
                 "ip_address": "10.0.0.3"
             }
         ],
+        "allowed_address_pairs": [
+          {
+            "ip_address": "10.0.0.4",
+            "mac_address": "fa:16:3e:c9:cb:f0"
+          }
+        ],
         "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
         "security_groups": [
             "f0ac4394-7e4a-4409-9701-ba8be283dbc3"
@@ -294,6 +323,9 @@
 			IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"},
 		},
 		SecurityGroups: []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"},
+		AllowedAddressPairs: []AddressPair{
+			AddressPair{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
+		},
 	}
 
 	s, err := Update(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract()
@@ -303,6 +335,9 @@
 	th.AssertDeepEquals(t, s.FixedIPs, []IP{
 		IP{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.3"},
 	})
+	th.AssertDeepEquals(t, s.AllowedAddressPairs, []AddressPair{
+		AddressPair{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
+	})
 	th.AssertDeepEquals(t, s.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"})
 }
 
diff --git a/openstack/networking/v2/ports/results.go b/openstack/networking/v2/ports/results.go
index 2511ff5..1f7eea1 100644
--- a/openstack/networking/v2/ports/results.go
+++ b/openstack/networking/v2/ports/results.go
@@ -19,7 +19,6 @@
 	var res struct {
 		Port *Port `json:"port"`
 	}
-
 	err := mapstructure.Decode(r.Body, &res)
 
 	return res.Port, err
@@ -51,6 +50,11 @@
 	IPAddress string `mapstructure:"ip_address" json:"ip_address,omitempty"`
 }
 
+type AddressPair struct {
+	IPAddress  string `mapstructure:"ip_address" json:"ip_address,omitempty"`
+	MACAddress string `mapstructure:"mac_address" json:"mac_address,omitempty"`
+}
+
 // Port represents a Neutron port. See package documentation for a top-level
 // description of what this is.
 type Port struct {
@@ -78,6 +82,8 @@
 	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"`
+	// Identifies the list of IP addresses the port will recognize/accept
+	AllowedAddressPairs []AddressPair `mapstructure:"allowed_address_pairs" json:"allowed_address_pairs"`
 }
 
 // PortPage is the page returned by a pager when traversing over a collection
diff --git a/provider_client.go b/provider_client.go
index 9264355..53fce73 100644
--- a/provider_client.go
+++ b/provider_client.go
@@ -177,6 +177,9 @@
 		}
 	}
 
+	// Set connection parameter to close the connection immediately when we've got the response
+	req.Close = true
+	
 	// Issue the request.
 	resp, err := client.HTTPClient.Do(req)
 	if err != nil {
@@ -246,6 +249,8 @@
 		return []int{201, 202}
 	case method == "PUT":
 		return []int{201, 202}
+	case method == "PATCH":
+		return []int{200, 204}
 	case method == "DELETE":
 		return []int{202, 204}
 	}
@@ -299,6 +304,24 @@
 	return client.Request("PUT", url, *opts)
 }
 
+func (client *ProviderClient) Patch(url string, JSONBody interface{}, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) {
+	if opts == nil {
+		opts = &RequestOpts{}
+	}
+
+	if v, ok := (JSONBody).(io.ReadSeeker); ok {
+		opts.RawBody = v
+	} else if JSONBody != nil {
+		opts.JSONBody = JSONBody
+	}
+
+	if JSONResponse != nil {
+		opts.JSONResponse = JSONResponse
+	}
+
+	return client.Request("PATCH", url, *opts)
+}
+
 func (client *ProviderClient) Delete(url string, opts *RequestOpts) (*http.Response, error) {
 	if opts == nil {
 		opts = &RequestOpts{}
diff --git a/rackspace/db/v1/backups/results.go b/rackspace/db/v1/backups/results.go
index 82b551d..04faf32 100644
--- a/rackspace/db/v1/backups/results.go
+++ b/rackspace/db/v1/backups/results.go
@@ -1,6 +1,8 @@
 package backups
 
 import (
+	"fmt"
+	"reflect"
 	"time"
 
 	"github.com/mitchellh/mapstructure"
@@ -109,12 +111,18 @@
 		Backups []Backup `mapstructure:"backups" json:"backups"`
 	}
 
-	err := mapstructure.Decode(casted, &resp)
+	if err := mapstructure.Decode(casted, &resp); err != nil {
+		return nil, err
+	}
 
 	var vals []interface{}
-	switch (casted).(type) {
-	case interface{}:
+	switch casted.(type) {
+	case map[string]interface{}:
 		vals = casted.(map[string]interface{})["backups"].([]interface{})
+	case map[string][]interface{}:
+		vals = casted.(map[string][]interface{})["backups"]
+	default:
+		return resp.Backups, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
 	}
 
 	for i, v := range vals {
@@ -137,5 +145,5 @@
 		}
 	}
 
-	return resp.Backups, err
+	return resp.Backups, nil
 }
diff --git a/rackspace/db/v1/instances/results.go b/rackspace/db/v1/instances/results.go
index 4b1317e..cdcc9c7 100644
--- a/rackspace/db/v1/instances/results.go
+++ b/rackspace/db/v1/instances/results.go
@@ -1,6 +1,8 @@
 package instances
 
 import (
+	"fmt"
+	"reflect"
 	"time"
 
 	"github.com/mitchellh/mapstructure"
@@ -147,16 +149,22 @@
 func ExtractInstances(page pagination.Page) ([]Instance, error) {
 	casted := page.(os.InstancePage).Body
 
-	var response struct {
+	var resp struct {
 		Instances []Instance `mapstructure:"instances"`
 	}
 
-	err := mapstructure.Decode(casted, &response)
+	if err := mapstructure.Decode(casted, &resp); err != nil {
+		return nil, err
+	}
 
 	var vals []interface{}
-	switch (casted).(type) {
-	case interface{}:
+	switch casted.(type) {
+	case map[string]interface{}:
 		vals = casted.(map[string]interface{})["instances"].([]interface{})
+	case map[string][]interface{}:
+		vals = casted.(map[string][]interface{})["instances"]
+	default:
+		return resp.Instances, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
 	}
 
 	for i, v := range vals {
@@ -165,19 +173,19 @@
 		if t, ok := val["created"].(string); ok && t != "" {
 			creationTime, err := time.Parse(time.RFC3339, t)
 			if err != nil {
-				return response.Instances, err
+				return resp.Instances, err
 			}
-			response.Instances[i].Created = creationTime
+			resp.Instances[i].Created = creationTime
 		}
 
 		if t, ok := val["updated"].(string); ok && t != "" {
 			updatedTime, err := time.Parse(time.RFC3339, t)
 			if err != nil {
-				return response.Instances, err
+				return resp.Instances, err
 			}
-			response.Instances[i].Updated = updatedTime
+			resp.Instances[i].Updated = updatedTime
 		}
 	}
 
-	return response.Instances, err
+	return resp.Instances, nil
 }
diff --git a/rackspace/lb/v1/nodes/requests.go b/rackspace/lb/v1/nodes/requests.go
index dc2d46c..9da376f 100644
--- a/rackspace/lb/v1/nodes/requests.go
+++ b/rackspace/lb/v1/nodes/requests.go
@@ -249,3 +249,38 @@
 		return NodeEventPage{pagination.SinglePageBase(r)}
 	})
 }
+
+// GetByIPPort locates a load balancer node by IP and port.
+func GetByIPPort(
+	client *gophercloud.ServiceClient,
+	loadBalancerID int,
+	address string,
+	port int,
+) (*Node, error) {
+
+	// nil until found
+	var found *Node
+
+	List(client, loadBalancerID, nil).EachPage(func(page pagination.Page) (bool, error) {
+		lbNodes, err := ExtractNodes(page)
+		if err != nil {
+			return false, err
+		}
+
+		for _, trialNode := range lbNodes {
+			if trialNode.Address == address && trialNode.Port == port {
+				found = &trialNode
+				return false, nil
+			}
+
+		}
+
+		return true, nil
+	})
+
+	if found == nil {
+		return nil, errors.New("Unable to get node by IP and Port")
+	}
+
+	return found, nil
+}