change all time fields to have type time.Time (#190)

* add Volume.Unmarshal

* add volumetenants.VolumeExt.Unmarshal

* create servers.Server time.Time fields

* json.Unmarshal can correctly handle time.RFC3339 (Server time fields)

* add v3 Token UnmarshalJSON method

* check for empty string when unmarshaling time

* add Member UnmarshalJSON

* v3 tokens.Token ExtractInto

* v3 trust.Trust UnmarshalJSON

* time.Time fields swift response objects

* time.Time fields for orchestration response objects

* time.Time fields for shared file systems response objects

* if we don't use pointers for the custom time fields, we don't need to check if they're nil

* style guide fixes: 'r' for receiver, 's' for struct

* remove unnecessary pointers from UnmarshalJSON methods
diff --git a/openstack/identity/v3/extensions/trusts/results.go b/openstack/identity/v3/extensions/trusts/results.go
index 3d3c7f2..bdd8e84 100644
--- a/openstack/identity/v3/extensions/trusts/results.go
+++ b/openstack/identity/v3/extensions/trusts/results.go
@@ -1,7 +1,5 @@
 package trusts
 
-import "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
-
 type TrusteeUser struct {
 	ID string `json:"id"`
 }
@@ -19,11 +17,6 @@
 	RedelegationCount  int         `json:"redelegation_count"`
 }
 
-type Token struct {
-	tokens.Token
-	Trust Trust `json:"OS-TRUST:trust"`
-}
-
 type TokenExt struct {
-	Token Token `json:"token"`
+	Trust Trust `json:"OS-TRUST:trust"`
 }
diff --git a/openstack/identity/v3/extensions/trusts/testing/fixtures.go b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
index b4106a3..e311526 100644
--- a/openstack/identity/v3/extensions/trusts/testing/fixtures.go
+++ b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
@@ -4,24 +4,13 @@
 	"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"
 )
 
 // HandleCreateTokenWithTrustID verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
 func HandleCreateTokenWithTrustID(t *testing.T, options tokens.AuthOptionsBuilder, requestJSON string) {
-	testhelper.SetupHTTP()
-	defer testhelper.TeardownHTTP()
-
-	client := gophercloud.ServiceClient{
-		ProviderClient: &gophercloud.ProviderClient{},
-		Endpoint:       testhelper.Endpoint(),
-	}
-
 	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "POST")
 		testhelper.TestHeader(t, r, "Content-Type", "application/json")
@@ -75,30 +64,4 @@
     }
 }`)
 	})
-
-	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/extensions/trusts/testing/requests_test.go b/openstack/identity/v3/extensions/trusts/testing/requests_test.go
index f0e41dc..f8a65ad 100644
--- a/openstack/identity/v3/extensions/trusts/testing/requests_test.go
+++ b/openstack/identity/v3/extensions/trusts/testing/requests_test.go
@@ -2,12 +2,18 @@
 
 import (
 	"testing"
+	"time"
 
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
+	th "github.com/gophercloud/gophercloud/testhelper"
+	"github.com/gophercloud/gophercloud/testhelper/client"
 )
 
 func TestCreateUserIDPasswordTrustID(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
 	ao := trusts.AuthOptsExt{
 		TrustID: "de0945a",
 		AuthOptionsBuilder: &tokens.AuthOptions{
@@ -32,4 +38,37 @@
 			}
 		}
 	`)
+
+	var actual struct {
+		tokens.Token
+		trusts.TokenExt
+	}
+	err := tokens.Create(client.ServiceClient(), ao).ExtractInto(&actual)
+	if err != nil {
+		t.Errorf("Create returned an error: %v", err)
+	}
+	expected := struct {
+		tokens.Token
+		trusts.TokenExt
+	}{
+		tokens.Token{
+			ExpiresAt: time.Date(2013, 02, 27, 18, 30, 59, 999999000, time.UTC),
+		},
+		trusts.TokenExt{
+			Trust: trusts.Trust{
+				ID:            "fe0aef",
+				Impersonation: false,
+				TrusteeUser: trusts.TrusteeUser{
+					ID: "0ca8f6",
+				},
+				TrustorUser: trusts.TrustorUser{
+					ID: "bd263c",
+				},
+				RedelegatedTrustID: "3ba234",
+				RedelegationCount:  2,
+			},
+		},
+	}
+
+	th.AssertDeepEquals(t, expected, actual)
 }
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index 2144a2b..0f1e8c2 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -1,7 +1,10 @@
 package tokens
 
-import "errors"
-import "github.com/gophercloud/gophercloud"
+import (
+	"time"
+
+	"github.com/gophercloud/gophercloud"
+)
 
 // Endpoint represents a single API endpoint offered by a service.
 // It matches either a public, internal or admin URL.
@@ -35,7 +38,7 @@
 
 // ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
 type ServiceCatalog struct {
-	Entries []CatalogEntry
+	Entries []CatalogEntry `json:"catalog"`
 }
 
 // commonResult is the deferred result of a Create or a Get call.
@@ -51,34 +54,23 @@
 
 // ExtractToken interprets a commonResult as a Token.
 func (r commonResult) ExtractToken() (*Token, error) {
-	var s struct {
-		Token *Token `json:"token"`
-	}
-
+	var s Token
 	err := r.ExtractInto(&s)
 	if err != nil {
 		return nil, err
 	}
 
-	if s.Token == nil {
-		return nil, errors.New("'token' missing in JSON response")
-	}
-
 	// Parse the token itself from the stored headers.
-	s.Token.ID = r.Header.Get("X-Subject-Token")
+	s.ID = r.Header.Get("X-Subject-Token")
 
-	return s.Token, err
+	return &s, err
 }
 
 // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
 func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
-	var s struct {
-		Token struct {
-			Entries []CatalogEntry `json:"catalog"`
-		} `json:"token"`
-	}
+	var s ServiceCatalog
 	err := r.ExtractInto(&s)
-	return &ServiceCatalog{Entries: s.Token.Entries}, err
+	return &s, err
 }
 
 // CreateResult defers the interpretation of a created token.
@@ -103,5 +95,9 @@
 	// ID is the issued token.
 	ID string `json:"id"`
 	// ExpiresAt is the timestamp at which this token will no longer be accepted.
-	ExpiresAt gophercloud.JSONRFC3339Milli `json:"expires_at"`
+	ExpiresAt time.Time `json:"expires_at"`
+}
+
+func (r commonResult) ExtractInto(v interface{}) error {
+	return r.ExtractIntoStructPtr(v, "token")
 }
diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go
index 27f3fdc..ddffeb4 100644
--- a/openstack/identity/v3/tokens/testing/requests_test.go
+++ b/openstack/identity/v3/tokens/testing/requests_test.go
@@ -39,10 +39,12 @@
 		options.Scope = *scope
 	}
 
-	_, err := tokens.Create(&client, &options).Extract()
-	if err != nil {
-		t.Errorf("Create returned an error: %v", err)
+	expected := &tokens.Token{
+		ExpiresAt: time.Date(2014, 10, 2, 13, 45, 0, 0, time.UTC),
 	}
+	actual, err := tokens.Create(&client, &options).Extract()
+	testhelper.AssertNoErr(t, err)
+	testhelper.CheckDeepEquals(t, expected, actual)
 }
 
 func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) {
@@ -423,7 +425,7 @@
 	}
 
 	expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014")
-	if token.ExpiresAt != gophercloud.JSONRFC3339Milli(expected) {
+	if token.ExpiresAt != expected {
 		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), time.Time(token.ExpiresAt).Format(time.UnixDate))
 	}
 }
@@ -526,7 +528,5 @@
 
 	options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"}
 	_, err := tokens.Create(&client, &options).Extract()
-	if err == nil {
-		t.Error("Create succeeded with no token returned")
-	}
+	testhelper.AssertNoErr(t, err)
 }