create trusts.TokenExt response object (#29)

* create trusts.TokenExt response object

* add redelegationcount, redelegatedtrustid fields
diff --git a/MIGRATING.md b/MIGRATING.md
index 62bdf8c..aa383c9 100644
--- a/MIGRATING.md
+++ b/MIGRATING.md
@@ -21,3 +21,12 @@
   }
   res := servers.Reboot(client, server.ID, rebootOpts)
   ```
+
+# Identity
+
+## V3
+
+### Tokens
+
+* `Token.ExpiresAt` is now of type `gophercloud.JSONRFC3339Milli` instead of
+  `time.Time`
diff --git a/openstack/identity/v3/extensions/trusts/results.go b/openstack/identity/v3/extensions/trusts/results.go
new file mode 100644
index 0000000..3d3c7f2
--- /dev/null
+++ b/openstack/identity/v3/extensions/trusts/results.go
@@ -0,0 +1,29 @@
+package trusts
+
+import "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
+
+type TrusteeUser struct {
+	ID string `json:"id"`
+}
+
+type TrustorUser struct {
+	ID string `json:"id"`
+}
+
+type Trust struct {
+	ID                 string      `json:"id"`
+	Impersonation      bool        `json:"impersonation"`
+	TrusteeUser        TrusteeUser `json:"trustee_user"`
+	TrustorUser        TrustorUser `json:"trustor_user"`
+	RedelegatedTrustID string      `json:"redelegated_trust_id"`
+	RedelegationCount  int         `json:"redelegation_count"`
+}
+
+type Token struct {
+	tokens.Token
+	Trust Trust `json:"OS-TRUST:trust"`
+}
+
+type TokenExt struct {
+	Token Token `json:"token"`
+}
diff --git a/openstack/identity/v3/extensions/trusts/testing/fixtures.go b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
index 15d5f3f..b4106a3 100644
--- a/openstack/identity/v3/extensions/trusts/testing/fixtures.go
+++ b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
@@ -4,8 +4,10 @@
 	"fmt"
 	"net/http"
 	"testing"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
+	"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
 	"github.com/gophercloud/gophercloud/testhelper"
 )
@@ -28,14 +30,75 @@
 
 		w.WriteHeader(http.StatusCreated)
 		fmt.Fprintf(w, `{
-			"token": {
-				"expires_at": "2014-10-02T13:45:00.000000Z"
-			}
-		}`)
+    "token": {
+        "expires_at": "2013-02-27T18:30:59.999999Z",
+        "issued_at": "2013-02-27T16:30:59.999999Z",
+        "methods": [
+            "password"
+        ],
+        "OS-TRUST:trust": {
+            "id": "fe0aef",
+            "impersonation": false,
+						"redelegated_trust_id": "3ba234",
+						"redelegation_count": 2,
+            "links": {
+                "self": "http://example.com/identity/v3/trusts/fe0aef"
+            },
+            "trustee_user": {
+                "id": "0ca8f6",
+                "links": {
+                    "self": "http://example.com/identity/v3/users/0ca8f6"
+                }
+            },
+            "trustor_user": {
+                "id": "bd263c",
+                "links": {
+                    "self": "http://example.com/identity/v3/users/bd263c"
+                }
+            }
+        },
+        "user": {
+            "domain": {
+                "id": "1789d1",
+                "links": {
+                    "self": "http://example.com/identity/v3/domains/1789d1"
+                },
+                "name": "example.com"
+            },
+            "email": "joe@example.com",
+            "id": "0ca8f6",
+            "links": {
+                "self": "http://example.com/identity/v3/users/0ca8f6"
+            },
+            "name": "Joe"
+        }
+    }
+}`)
 	})
 
-	_, err := tokens.Create(&client, options).Extract()
+	var actual trusts.TokenExt
+	err := tokens.Create(&client, options).ExtractInto(&actual)
 	if err != nil {
 		t.Errorf("Create returned an error: %v", err)
 	}
+	expected := trusts.TokenExt{
+		Token: trusts.Token{
+			Token: tokens.Token{
+				ExpiresAt: gophercloud.JSONRFC3339Milli(time.Date(2013, 02, 27, 18, 30, 59, 999999000, time.UTC)),
+			},
+			Trust: trusts.Trust{
+				ID:            "fe0aef",
+				Impersonation: false,
+				TrusteeUser: trusts.TrusteeUser{
+					ID: "0ca8f6",
+				},
+				TrustorUser: trusts.TrustorUser{
+					ID: "bd263c",
+				},
+				RedelegatedTrustID: "3ba234",
+				RedelegationCount:  2,
+			},
+		},
+	}
+	testhelper.AssertDeepEquals(t, expected, actual)
 }
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index d6917f9..4b362cc 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -1,10 +1,6 @@
 package tokens
 
-import (
-	"time"
-
-	"github.com/gophercloud/gophercloud"
-)
+import "github.com/gophercloud/gophercloud"
 
 // Endpoint represents a single API endpoint offered by a service.
 // It matches either a public, internal or admin URL.
@@ -55,24 +51,18 @@
 // ExtractToken interprets a commonResult as a Token.
 func (r commonResult) ExtractToken() (*Token, error) {
 	var s struct {
-		Token struct {
-			ExpiresAt gophercloud.JSONRFC3339Milli `json:"expires_at"`
-		} `json:"token"`
+		Token *Token `json:"token"`
 	}
 
-	var token Token
-
-	// Parse the token itself from the stored headers.
-	token.ID = r.Header.Get("X-Subject-Token")
-
 	err := r.ExtractInto(&s)
 	if err != nil {
 		return nil, err
 	}
 
-	token.ExpiresAt = time.Time(s.Token.ExpiresAt)
+	// Parse the token itself from the stored headers.
+	s.Token.ID = r.Header.Get("X-Subject-Token")
 
-	return &token, err
+	return s.Token, err
 }
 
 // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
@@ -113,8 +103,7 @@
 // Each Token is valid for a set length of time.
 type Token struct {
 	// ID is the issued token.
-	ID string
-
+	ID string `json:"id"`
 	// ExpiresAt is the timestamp at which this token will no longer be accepted.
-	ExpiresAt time.Time
+	ExpiresAt gophercloud.JSONRFC3339Milli `json:"expires_at"`
 }
diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go
index 481d05c..195fa5a 100644
--- a/openstack/identity/v3/tokens/testing/requests_test.go
+++ b/openstack/identity/v3/tokens/testing/requests_test.go
@@ -423,8 +423,8 @@
 	}
 
 	expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014")
-	if token.ExpiresAt != expected {
-		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), token.ExpiresAt.Format(time.UnixDate))
+	if token.ExpiresAt != gophercloud.JSONRFC3339Milli(expected) {
+		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), time.Time(token.ExpiresAt).Format(time.UnixDate))
 	}
 }