Add support for Listing Servers.

Up to now, all you could do is authenticate with Gophercloud.  Now, you
can list your servers too!

This is a pretty straight-ahead port of logic from Gorax to Gophercloud.

After you gain access to the ComputeApi, you simply invoke
ListServers().  This returns a slice of Server structures, one each for
the servers your account has access to.  See the 02-list-servers.go
acceptance test.

Note that no unit-level tests exist for this functionality.  Writing a
unit test for this code would only serve to test the compiler's ability
to emit bug-free machine code.  (Observe ListServers() has no control
flow points, and all its dependencies already have their own unit
tests.)

Being that this is a straight-ahead port from Gorax, some things remain
to be done:

1) Provide an API for accessing Rackspace-specific fields. (#34)
2) Assuming (1) is successful, remove Rack-specific fields from Server
   and other structures of interest. (#34)
3) Rename ComputeApi to something more descriptive -- like ServerApi().
   (#33)
4) Implement token re-authentication logic.  (#12)
diff --git a/authenticate.go b/authenticate.go
index d460673..8b87e44 100644
--- a/authenticate.go
+++ b/authenticate.go
@@ -134,3 +134,8 @@
 	urls := []string{ep.PublicURL, ep.InternalURL}
 	return urls[ac.UrlChoice]
 }
+
+// See AccessProvider interface definition for details.
+func (a *Access) AuthToken() string {
+	return a.Token.Id
+}
diff --git a/common_types.go b/common_types.go
new file mode 100644
index 0000000..4e3d32c
--- /dev/null
+++ b/common_types.go
@@ -0,0 +1,9 @@
+package gophercloud
+
+// Link is used for JSON (un)marshalling.
+// It provides RESTful links to a resource.
+type Link struct {
+	Href string `json:"href"`
+	Rel  string `json:"rel"`
+	Type string `json:"type"`
+}
diff --git a/context.go b/context.go
index 71ff757..1b5d390 100644
--- a/context.go
+++ b/context.go
@@ -87,6 +87,7 @@
 	gcp := &genericCloudProvider{
 		endpoint: url,
 		context:  c,
+		access:   acc,
 	}
 
 	return gcp, nil
diff --git a/flavors.go b/flavors.go
new file mode 100644
index 0000000..909a308
--- /dev/null
+++ b/flavors.go
@@ -0,0 +1,9 @@
+package gophercloud
+
+// FlavorLink provides a reference to a flavor by either ID or by direct URL.
+// Some services use just the ID, others use just the URL.
+// This structure provides a common means of expressing both in a single field.
+type FlavorLink struct {
+	Id    string `json:"id"`
+	Links []Link `json:"links"`
+}
diff --git a/images.go b/images.go
new file mode 100644
index 0000000..95dad59
--- /dev/null
+++ b/images.go
@@ -0,0 +1,9 @@
+package gophercloud
+
+// ImageLink provides a reference to a image by either ID or by direct URL.
+// Some services use just the ID, others use just the URL.
+// This structure provides a common means of expressing both in a single field.
+type ImageLink struct {
+	Id    string `json:"id"`
+	Links []Link `json:"links"`
+}
diff --git a/interfaces.go b/interfaces.go
index 671fa1a..63439c5 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -8,6 +8,11 @@
 	// endpoint, depending on both its existence and the setting of the ApiCriteria.UrlChoice
 	// field.
 	FirstEndpointUrlByCriteria(ApiCriteria) string
+
+	// TODO(sfalvo): get Token() to automatically renew the authentication token if it's near expiry.
+
+	// AuthToken provides a copy of the current authentication token for the user's credentials.
+	AuthToken() string
 }
 
 // ComputeProvider instances encapsulate a Cloud Servers API, should one exist in the service catalog
diff --git a/servers.go b/servers.go
index f6214c0..e3bc547 100644
--- a/servers.go
+++ b/servers.go
@@ -1,5 +1,12 @@
+// TODO(sfalvo): Remove Rackspace-specific Server structure fields and refactor them into a provider-specific access method.
+// Be sure to update godocs accordingly.
+
 package gophercloud
 
+import (
+	"github.com/racker/perigee"
+)
+
 // genericCloudProvider structures provide the implementation for generic OpenStack-compatible
 // ComputeProvider interfaces.
 type genericCloudProvider struct {
@@ -9,14 +16,148 @@
 
 	// Test context (if any) in which to issue requests.
 	context *Context
+
+	// access associates this API provider with a set of credentials,
+	// which may be automatically renewed if they near expiration.
+	access AccessProvider
 }
 
 // See the ComputeProvider interface for details.
 func (gcp *genericCloudProvider) ListServers() ([]Server, error) {
-	return nil, nil
+	var ss []Server
+
+	url := gcp.endpoint + "/servers"
+	err := perigee.Get(url, perigee.Options{
+		CustomClient: gcp.context.httpClient,
+		Results:      &struct{ Servers *[]Server }{&ss},
+		MoreHeaders: map[string]string{
+			"X-Auth-Token": gcp.access.AuthToken(),
+		},
+	})
+	return ss, err
 }
 
-// Server structures provide data about a server running in your provider's cloud.
+// RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
+type RaxBandwidth struct {
+	AuditPeriodEnd    string `json:"audit_period_end"`
+	AuditPeriodStart  string `json:"audit_period_start"`
+	BandwidthInbound  int64  `json:"bandwidth_inbound"`
+	BandwidthOutbound int64  `json:"bandwidth_outbound"`
+	Interface         string `json:"interface"`
+}
+
+// A VersionedAddress denotes either an IPv4 or IPv6 (depending on version indicated)
+// address.
+type VersionedAddress struct {
+	Addr    string `json:"addr"`
+	Version int    `json:"version"`
+}
+
+// An AddressSet provides a set of public and private IP addresses for a resource.
+// Each address has a version to identify if IPv4 or IPv6.
+type AddressSet struct {
+	Public  []VersionedAddress `json:"public"`
+	Private []VersionedAddress `json:"private"`
+}
+
+// Server records represent (virtual) hardware instances (not configurations) accessible by the user.
+//
+// The AccessIPv4 / AccessIPv6 fields provides IP addresses for the server in the IPv4 or IPv6 format, respectively.
+//
+// Addresses provides addresses for any attached isolated networks.
+// The version field indicates whether the IP address is version 4 or 6.
+//
+// Created tells when the server entity was created.
+//
+// The Flavor field includes the flavor ID and flavor links.
+//
+// The compute provisioning algorithm has an anti-affinity property that
+// attempts to spread customer VMs across hosts.
+// Under certain situations,
+// VMs from the same customer might be placed on the same host.
+// The HostId field represents the host your server runs on and
+// can be used to determine this scenario if it is relevant to your application.
+// Note that HostId is unique only per account; it is not globally unique.
+// 
+// Id provides the server's unique identifier.
+// This field must be treated opaquely.
+//
+// Image indicates which image is installed on the server.
+//
+// Links provides one or more means of accessing the server.
+//
+// Metadata provides a small key-value store for application-specific information.
+//
+// Name provides a human-readable name for the server.
+//
+// Progress indicates how far along it is towards being provisioned.
+// 100 represents complete, while 0 represents just beginning.
+//
+// Status provides an indication of what the server's doing at the moment.
+// A server will be in ACTIVE state if it's ready for use.
+//
+// OsDcfDiskConfig indicates the server's boot volume configuration.
+// Valid values are:
+//     AUTO
+//     ----
+//     The server is built with a single partition the size of the target flavor disk.
+//     The file system is automatically adjusted to fit the entire partition.
+//     This keeps things simple and automated.
+//     AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
+//     This is the default setting for applicable Rackspace base images.
+//
+//     MANUAL
+//     ------
+//     The server is built using whatever partition scheme and file system is in the source image.
+//     If the target flavor disk is larger,
+//     the remaining disk space is left unpartitioned.
+//     This enables images to have non-EXT3 file systems, multiple partitions, and so on,
+//     and enables you to manage the disk configuration.
+//
+// RaxBandwidth provides measures of the server's inbound and outbound bandwidth per interface.
+//
+// OsExtStsPowerState provides an indication of the server's power.
+// This field appears to be a set of flag bits:
+//
+//           ... 4  3   2   1   0
+//         +--//--+---+---+---+---+
+//         | .... | 0 | S | 0 | I |
+//         +--//--+---+---+---+---+
+//                      |       |
+//                      |       +---  0=Instance is down.
+//                      |             1=Instance is up.
+//                      |
+//                      +-----------  0=Server is switched ON.
+//                                    1=Server is switched OFF.
+//                                    (note reverse logic.)
+//
+// Unused bits should be ignored when read, and written as 0 for future compatibility.
+//
+// OsExtStsTaskState and OsExtStsVmState work together
+// to provide visibility in the provisioning process for the instance.
+// Consult Rackspace documentation at
+// http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#ext_status
+// for more details.  It's too lengthy to include here.
 type Server struct {
-	Id string
+	AccessIPv4         string         `json:"accessIPv4"`
+	AccessIPv6         string         `json:"accessIPv6"`
+	Addresses          AddressSet     `json:"addresses"`
+	Created            string         `json:"created"`
+	Flavor             FlavorLink     `json:"flavor"`
+	HostId             string         `json:"hostId"`
+	Id                 string         `json:"id"`
+	Image              ImageLink      `json:"image"`
+	Links              []Link         `json:"links"`
+	Metadata           interface{}    `json:"metadata"`
+	Name               string         `json:"name"`
+	Progress           int            `json:"progress"`
+	Status             string         `json:"status"`
+	TenantId           string         `json:"tenant_id"`
+	Updated            string         `json:"updated"`
+	UserId             string         `json:"user_id"`
+	OsDcfDiskConfig    string         `json:"OS-DCF:diskConfig"`
+	RaxBandwidth       []RaxBandwidth `json:"rax-bandwidth:bandwidth"`
+	OsExtStsPowerState int            `json:"OS-EXT-STS:power_state"`
+	OsExtStsTaskState  string         `json:"OS-EXT-STS:task_state"`
+	OsExtStsVmState    string         `json:"OS-EXT-STS:vm_state"`
 }
diff --git a/servers_test.go b/servers_test.go
index 206290f..e296801 100644
--- a/servers_test.go
+++ b/servers_test.go
@@ -16,6 +16,10 @@
 	return urls[ac.UrlChoice]
 }
 
+func (ta *testAccess) AuthToken() string {
+	return ""
+}
+
 func TestGetServersApi(t *testing.T) {
 	c := TestContext().UseCustomClient(&http.Client{Transport: newTransport().WithResponse("Hello")})