Fix api interfaces for orchestration resources

Some of the interfaces don't correspond well to the values
expected by the requests and returned by api.
diff --git a/openstack/orchestration/v1/stackresources/fixtures.go b/openstack/orchestration/v1/stackresources/fixtures.go
index c3c3d3f..2273ba7 100644
--- a/openstack/orchestration/v1/stackresources/fixtures.go
+++ b/openstack/orchestration/v1/stackresources/fixtures.go
@@ -28,10 +28,13 @@
 		LogicalID:    "hello_world",
 		StatusReason: "state changed",
 		UpdatedTime:  time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+		CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
 		RequiredBy:   []interface{}{},
 		Status:       "CREATE_IN_PROGRESS",
 		PhysicalID:   "49181cd6-169a-4130-9455-31185bbfc5bf",
 		Type:         "OS::Nova::Server",
+		Attributes:   map[string]interface{}{"SXSW": "atx"},
+		Description:  "Some resource",
 	},
 }
 
@@ -40,6 +43,8 @@
 {
   "resources": [
   {
+  	"description": "Some resource",
+  	"attributes": {"SXSW": "atx"},
     "resource_name": "hello_world",
     "links": [
       {
@@ -54,6 +59,7 @@
     "logical_resource_id": "hello_world",
     "resource_status_reason": "state changed",
     "updated_time": "2015-02-05T21:33:11",
+	"creation_time": "2015-02-05T21:33:10",
     "required_by": [],
     "resource_status": "CREATE_IN_PROGRESS",
     "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
@@ -93,10 +99,13 @@
 		LogicalID:    "hello_world",
 		StatusReason: "state changed",
 		UpdatedTime:  time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+		CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
 		RequiredBy:   []interface{}{},
 		Status:       "CREATE_IN_PROGRESS",
 		PhysicalID:   "49181cd6-169a-4130-9455-31185bbfc5bf",
 		Type:         "OS::Nova::Server",
+		Attributes:   map[string]interface{}{"SXSW": "atx"},
+		Description:  "Some resource",
 	},
 }
 
@@ -121,7 +130,10 @@
     "required_by": [],
     "resource_status": "CREATE_IN_PROGRESS",
     "physical_resource_id": "49181cd6-169a-4130-9455-31185bbfc5bf",
-    "resource_type": "OS::Nova::Server"
+	"creation_time": "2015-02-05T21:33:10",
+    "resource_type": "OS::Nova::Server",
+	"attributes": {"SXSW": "atx"},
+	"description": "Some resource"
   }
 ]
 }`
@@ -162,6 +174,7 @@
 		},
 	},
 	LogicalID:    "wordpress_instance",
+	Attributes:   map[string]interface{}{"SXSW": "atx"},
 	StatusReason: "state changed",
 	UpdatedTime:  time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC),
 	RequiredBy:   []interface{}{},
@@ -174,6 +187,8 @@
 const GetOutput = `
 {
   "resource": {
+    "description": "Some resource",
+    "attributes": {"SXSW": "atx"},
     "resource_name": "wordpress_instance",
     "description": "",
     "links": [
@@ -240,7 +255,7 @@
 }
 
 // ListTypesExpected represents the expected object from a ListTypes request.
-var ListTypesExpected = []string{
+var ListTypesExpected = resourceTypes{
 	"OS::Nova::Server",
 	"OS::Heat::RandomString",
 	"OS::Swift::Container",
@@ -251,6 +266,18 @@
 	"OS::Nova::KeyPair",
 }
 
+// same as above, but sorted
+var SortedListTypesExpected = resourceTypes{
+	"OS::Cinder::VolumeAttachment",
+	"OS::Heat::RandomString",
+	"OS::Nova::FloatingIP",
+	"OS::Nova::FloatingIPAssociation",
+	"OS::Nova::KeyPair",
+	"OS::Nova::Server",
+	"OS::Swift::Container",
+	"OS::Trove::Instance",
+}
+
 // ListTypesOutput represents the response body from a ListTypes request.
 const ListTypesOutput = `
 {
@@ -296,6 +323,11 @@
 		},
 	},
 	ResourceType: "OS::Heat::AResourceName",
+	SupportStatus: map[string]interface{}{
+		"message": "A status message",
+		"status":  "SUPPORTED",
+		"version": "2014.1",
+	},
 }
 
 // GetSchemaOutput represents the response body from a Schema request.
@@ -314,7 +346,12 @@
       "description": "A resource description."
     }
   },
-  "resource_type": "OS::Heat::AResourceName"
+  "resource_type": "OS::Heat::AResourceName",
+  "support_status": {
+	"message": "A status message",
+	"status": "SUPPORTED",
+	"version": "2014.1"
+  }
 }`
 
 // HandleGetSchemaSuccessfully creates an HTTP handler at `/resource_types/OS::Heat::AResourceName`
@@ -332,56 +369,7 @@
 }
 
 // GetTemplateExpected represents the expected object from a Template request.
-var GetTemplateExpected = &TypeTemplate{
-	HeatTemplateFormatVersion: "2012-12-12",
-	Outputs: map[string]interface{}{
-		"private_key": map[string]interface{}{
-			"Description": "The private key if it has been saved.",
-			"Value":       "{\"Fn::GetAtt\": [\"KeyPair\", \"private_key\"]}",
-		},
-		"public_key": map[string]interface{}{
-			"Description": "The public key.",
-			"Value":       "{\"Fn::GetAtt\": [\"KeyPair\", \"public_key\"]}",
-		},
-	},
-	Parameters: map[string]interface{}{
-		"name": map[string]interface{}{
-			"Description": "The name of the key pair.",
-			"Type":        "String",
-		},
-		"public_key": map[string]interface{}{
-			"Description": "The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.",
-			"Type":        "String",
-		},
-		"save_private_key": map[string]interface{}{
-			"AllowedValues": []string{
-				"True",
-				"true",
-				"False",
-				"false",
-			},
-			"Default":     false,
-			"Description": "True if the system should remember a generated private key; False otherwise.",
-			"Type":        "String",
-		},
-	},
-	Resources: map[string]interface{}{
-		"KeyPair": map[string]interface{}{
-			"Properties": map[string]interface{}{
-				"name": map[string]interface{}{
-					"Ref": "name",
-				},
-				"public_key": map[string]interface{}{
-					"Ref": "public_key",
-				},
-				"save_private_key": map[string]interface{}{
-					"Ref": "save_private_key",
-				},
-			},
-			"Type": "OS::Nova::KeyPair",
-		},
-	},
-}
+var GetTemplateExpected = "{\n  \"HeatTemplateFormatVersion\": \"2012-12-12\",\n  \"Outputs\": {\n    \"private_key\": {\n      \"Description\": \"The private key if it has been saved.\",\n      \"Value\": \"{\\\"Fn::GetAtt\\\": [\\\"KeyPair\\\", \\\"private_key\\\"]}\"\n    },\n    \"public_key\": {\n      \"Description\": \"The public key.\",\n      \"Value\": \"{\\\"Fn::GetAtt\\\": [\\\"KeyPair\\\", \\\"public_key\\\"]}\"\n    }\n  },\n  \"Parameters\": {\n    \"name\": {\n      \"Description\": \"The name of the key pair.\",\n      \"Type\": \"String\"\n    },\n    \"public_key\": {\n      \"Description\": \"The optional public key. This allows users to supply the public key from a pre-existing key pair. If not supplied, a new key pair will be generated.\",\n      \"Type\": \"String\"\n    },\n    \"save_private_key\": {\n      \"AllowedValues\": [\n        \"True\",\n        \"true\",\n        \"False\",\n        \"false\"\n      ],\n      \"Default\": false,\n      \"Description\": \"True if the system should remember a generated private key; False otherwise.\",\n      \"Type\": \"String\"\n    }\n  },\n  \"Resources\": {\n    \"KeyPair\": {\n      \"Properties\": {\n        \"name\": {\n          \"Ref\": \"name\"\n        },\n        \"public_key\": {\n          \"Ref\": \"public_key\"\n        },\n        \"save_private_key\": {\n          \"Ref\": \"save_private_key\"\n        }\n      },\n      \"Type\": \"OS::Nova::KeyPair\"\n    }\n  }\n}"
 
 // GetTemplateOutput represents the response body from a Template request.
 const GetTemplateOutput = `
diff --git a/openstack/orchestration/v1/stackresources/requests_test.go b/openstack/orchestration/v1/stackresources/requests_test.go
index f137878..e5045a7 100644
--- a/openstack/orchestration/v1/stackresources/requests_test.go
+++ b/openstack/orchestration/v1/stackresources/requests_test.go
@@ -1,6 +1,7 @@
 package stackresources
 
 import (
+	"sort"
 	"testing"
 
 	"github.com/rackspace/gophercloud/pagination"
@@ -75,6 +76,9 @@
 		th.AssertNoErr(t, err)
 
 		th.CheckDeepEquals(t, ListTypesExpected, actual)
+		// test if sorting works
+		sort.Sort(actual)
+		th.CheckDeepEquals(t, SortedListTypesExpected, actual)
 
 		return true, nil
 	})
@@ -103,5 +107,5 @@
 	th.AssertNoErr(t, err)
 
 	expected := GetTemplateExpected
-	th.AssertDeepEquals(t, expected, actual)
+	th.AssertDeepEquals(t, expected, string(actual))
 }
diff --git a/openstack/orchestration/v1/stackresources/results.go b/openstack/orchestration/v1/stackresources/results.go
index df79d58..51c3c0c 100644
--- a/openstack/orchestration/v1/stackresources/results.go
+++ b/openstack/orchestration/v1/stackresources/results.go
@@ -1,6 +1,7 @@
 package stackresources
 
 import (
+	"encoding/json"
 	"fmt"
 	"reflect"
 	"time"
@@ -12,15 +13,18 @@
 
 // Resource represents a stack resource.
 type Resource struct {
-	Links        []gophercloud.Link `mapstructure:"links"`
-	LogicalID    string             `mapstructure:"logical_resource_id"`
-	Name         string             `mapstructure:"resource_name"`
-	PhysicalID   string             `mapstructure:"physical_resource_id"`
-	RequiredBy   []interface{}      `mapstructure:"required_by"`
-	Status       string             `mapstructure:"resource_status"`
-	StatusReason string             `mapstructure:"resource_status_reason"`
-	Type         string             `mapstructure:"resource_type"`
-	UpdatedTime  time.Time          `mapstructure:"-"`
+	Attributes   map[string]interface{} `mapstructure:"attributes"`
+	CreationTime time.Time              `mapstructure:"-"`
+	Description  string                 `mapstructure:"description"`
+	Links        []gophercloud.Link     `mapstructure:"links"`
+	LogicalID    string                 `mapstructure:"logical_resource_id"`
+	Name         string                 `mapstructure:"resource_name"`
+	PhysicalID   string                 `mapstructure:"physical_resource_id"`
+	RequiredBy   []interface{}          `mapstructure:"required_by"`
+	Status       string                 `mapstructure:"resource_status"`
+	StatusReason string                 `mapstructure:"resource_status_reason"`
+	Type         string                 `mapstructure:"resource_type"`
+	UpdatedTime  time.Time              `mapstructure:"-"`
 }
 
 // FindResult represents the result of a Find operation.
@@ -54,6 +58,13 @@
 			}
 			res.Res[i].UpdatedTime = t
 		}
+		if date, ok := resource["creation_time"]; ok && date != nil {
+			t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
+			if err != nil {
+				return nil, err
+			}
+			res.Res[i].CreationTime = t
+		}
 	}
 
 	return res.Res, nil
@@ -75,18 +86,6 @@
 	return len(resources) == 0, nil
 }
 
-// LastMarker returns the last container name in a ListResult.
-func (r ResourcePage) LastMarker() (string, error) {
-	resources, err := ExtractResources(r)
-	if err != nil {
-		return "", err
-	}
-	if len(resources) == 0 {
-		return "", nil
-	}
-	return resources[len(resources)-1].PhysicalID, nil
-}
-
 // ExtractResources interprets the results of a single page from a List() call, producing a slice of Resource entities.
 func ExtractResources(page pagination.Page) ([]Resource, error) {
 	casted := page.(ResourcePage).Body
@@ -94,8 +93,9 @@
 	var response struct {
 		Resources []Resource `mapstructure:"resources"`
 	}
-	err := mapstructure.Decode(casted, &response)
-
+	if err := mapstructure.Decode(casted, &response); err != nil {
+		return nil, err
+	}
 	var resources []interface{}
 	switch casted.(type) {
 	case map[string]interface{}:
@@ -115,9 +115,16 @@
 			}
 			response.Resources[i].UpdatedTime = t
 		}
+		if date, ok := resource["creation_time"]; ok && date != nil {
+			t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
+			if err != nil {
+				return nil, err
+			}
+			response.Resources[i].CreationTime = t
+		}
 	}
 
-	return response.Resources, err
+	return response.Resources, nil
 }
 
 // GetResult represents the result of a Get operation.
@@ -149,6 +156,13 @@
 		}
 		res.Res.UpdatedTime = t
 	}
+	if date, ok := resource["creation_time"]; ok && date != nil {
+		t, err := time.Parse(gophercloud.STACK_TIME_FMT, date.(string))
+		if err != nil {
+			return nil, err
+		}
+		res.Res.CreationTime = t
+	}
 
 	return res.Res, nil
 }
@@ -192,21 +206,42 @@
 	return len(rts) == 0, nil
 }
 
+// resourceTypes represents the type that holds the result of ExtractResourceTypes.
+// We define methods on this type to sort it before output
+type resourceTypes []string
+
+func (r resourceTypes) Len() int {
+	return len(r)
+}
+
+func (r resourceTypes) Swap(i, j int) {
+	r[i], r[j] = r[j], r[i]
+}
+
+func (r resourceTypes) Less(i, j int) bool {
+	return r[i] < r[j]
+}
+
 // ExtractResourceTypes extracts and returns resource types.
-func ExtractResourceTypes(page pagination.Page) ([]string, error) {
+func ExtractResourceTypes(page pagination.Page) (resourceTypes, error) {
+	casted := page.(ResourceTypePage).Body
+
 	var response struct {
-		ResourceTypes []string `mapstructure:"resource_types"`
+		ResourceTypes resourceTypes `mapstructure:"resource_types"`
 	}
 
-	err := mapstructure.Decode(page.(ResourceTypePage).Body, &response)
-	return response.ResourceTypes, err
+	if err := mapstructure.Decode(casted, &response); err != nil {
+		return nil, err
+	}
+	return response.ResourceTypes, nil
 }
 
 // TypeSchema represents a stack resource schema.
 type TypeSchema struct {
-	Attributes   map[string]interface{} `mapstructure:"attributes"`
-	Properties   map[string]interface{} `mapstrucutre:"properties"`
-	ResourceType string                 `mapstructure:"resource_type"`
+	Attributes    map[string]interface{} `mapstructure:"attributes"`
+	Properties    map[string]interface{} `mapstrucutre:"properties"`
+	ResourceType  string                 `mapstructure:"resource_type"`
+	SupportStatus map[string]interface{} `mapstructure:"support_status"`
 }
 
 // SchemaResult represents the result of a Schema operation.
@@ -230,31 +265,20 @@
 	return &res, nil
 }
 
-// TypeTemplate represents a stack resource template.
-type TypeTemplate struct {
-	HeatTemplateFormatVersion string
-	Outputs                   map[string]interface{}
-	Parameters                map[string]interface{}
-	Resources                 map[string]interface{}
-}
-
 // TemplateResult represents the result of a Template operation.
 type TemplateResult struct {
 	gophercloud.Result
 }
 
-// Extract returns a pointer to a TypeTemplate object and is called after a
+// Extract returns the template and is called after a
 // Template operation.
-func (r TemplateResult) Extract() (*TypeTemplate, error) {
+func (r TemplateResult) Extract() ([]byte, error) {
 	if r.Err != nil {
 		return nil, r.Err
 	}
-
-	var res TypeTemplate
-
-	if err := mapstructure.Decode(r.Body, &res); err != nil {
+	template, err := json.MarshalIndent(r.Body, "", "  ")
+	if err != nil {
 		return nil, err
 	}
-
-	return &res, nil
+	return template, nil
 }
diff --git a/openstack/orchestration/v1/stacks/fixtures.go b/openstack/orchestration/v1/stacks/fixtures.go
index 3a621da..f884d51 100644
--- a/openstack/orchestration/v1/stacks/fixtures.go
+++ b/openstack/orchestration/v1/stacks/fixtures.go
@@ -63,6 +63,7 @@
 		CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
 		Status:       "CREATE_COMPLETE",
 		ID:           "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+		Tags:         []string{"rackspace", "atx"},
 	},
 	ListedStack{
 		Description: "Simple template to test heat commands",
@@ -78,6 +79,7 @@
 		UpdatedTime:  time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC),
 		Status:       "UPDATE_COMPLETE",
 		ID:           "db6977b2-27aa-4775-9ae7-6213212d4ada",
+		Tags:         []string{"sfo", "satx"},
 	},
 }
 
@@ -98,7 +100,8 @@
     "creation_time": "2015-02-03T20:07:39",
     "updated_time": null,
     "stack_status": "CREATE_COMPLETE",
-    "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87"
+    "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+	"tags": ["rackspace", "atx"]
   },
   {
     "description": "Simple template to test heat commands",
@@ -113,7 +116,8 @@
     "creation_time": "2014-12-11T17:39:16",
     "updated_time": "2014-12-11T17:40:37",
     "stack_status": "UPDATE_COMPLETE",
-    "id": "db6977b2-27aa-4775-9ae7-6213212d4ada"
+    "id": "db6977b2-27aa-4775-9ae7-6213212d4ada",
+	"tags": ["sfo", "satx"]
   }
   ]
 }
@@ -165,6 +169,7 @@
 	Status:              "CREATE_COMPLETE",
 	ID:                  "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
 	TemplateDescription: "Simple template to test heat commands",
+	Tags:                []string{"rackspace", "atx"},
 }
 
 // GetOutput represents the response body from a Get request.
@@ -194,7 +199,8 @@
     "stack_status": "CREATE_COMPLETE",
     "updated_time": null,
     "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
-    "template_description": "Simple template to test heat commands"
+    "template_description": "Simple template to test heat commands",
+	"tags": ["rackspace", "atx"]
   }
 }
 `
@@ -248,7 +254,6 @@
 		"OS::stack_name": "postman_stack",
 		"OS::stack_id":   "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
 	},
-	StatusReason: "Stack CREATE completed successfully",
 	Name:         "postman_stack",
 	CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
 	Links: []gophercloud.Link{
@@ -259,7 +264,6 @@
 	},
 	Capabilities:        []interface{}{},
 	NotificationTopics:  []interface{}{},
-	Status:              "CREATE_COMPLETE",
 	ID:                  "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
 	TemplateDescription: "Simple template to test heat commands",
 }
@@ -316,6 +320,20 @@
 			"type":        "OS::Nova::Server",
 		},
 	},
+	Files: map[string]string{
+		"file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml": "heat_template_version: 2014-10-16\nparameters:\n  flavor:\n    type: string\n    description: Flavor for the server to be created\n    default: 4353\n    hidden: true\nresources:\n  test_server:\n    type: \"OS::Nova::Server\"\n    properties:\n      name: test-server\n      flavor: 2 GB General Purpose v1\n image: Debian 7 (Wheezy) (PVHVM)\n",
+	},
+	StackUserProjectID: "897686",
+	ProjectID:          "897686",
+	Environment: map[string]interface{}{
+		"encrypted_param_names": make([]map[string]interface{}, 0),
+		"parameter_defaults":    make(map[string]interface{}),
+		"parameters":            make(map[string]interface{}),
+		"resource_registry": map[string]interface{}{
+			"file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml": "file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml",
+			"resources": make(map[string]interface{}),
+		},
+	},
 }
 
 // AbandonOutput represents the response body from an Abandon request.
@@ -354,21 +372,35 @@
       "name": "hello_world",
       "resource_id": "8a310d36-46fc-436f-8be4-37a696b8ac63",
       "action": "CREATE",
-      "type": "OS::Nova::Server",
+      "type": "OS::Nova::Server"
     }
-  }
+  },
+  "files": {
+    "file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml": "heat_template_version: 2014-10-16\nparameters:\n  flavor:\n    type: string\n    description: Flavor for the server to be created\n    default: 4353\n    hidden: true\nresources:\n  test_server:\n    type: \"OS::Nova::Server\"\n    properties:\n      name: test-server\n      flavor: 2 GB General Purpose v1\n image: Debian 7 (Wheezy) (PVHVM)\n"
+},
+  "environment": {
+	"encrypted_param_names": [],
+	"parameter_defaults": {},
+	"parameters": {},
+	"resource_registry": {
+		"file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml": "file:///Users/prat8228/go/src/github.com/rackspace/rack/my_nova.yaml",
+		"resources": {}
+	}
+  },
+  "stack_user_project_id": "897686",
+  "project_id": "897686"
 }`
 
 // HandleAbandonSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/abandon`
 // on the test handler mux that responds with an `Abandon` response.
-func HandleAbandonSuccessfully(t *testing.T) {
-	th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87/abandon", func(w http.ResponseWriter, r *http.Request) {
+func HandleAbandonSuccessfully(t *testing.T, output string) {
+	th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c8/abandon", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "DELETE")
 		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
 		th.TestHeader(t, r, "Accept", "application/json")
 
 		w.Header().Set("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
-		fmt.Fprintf(w, AbandonOutput)
+		fmt.Fprintf(w, output)
 	})
 }
diff --git a/openstack/orchestration/v1/stacks/requests.go b/openstack/orchestration/v1/stacks/requests.go
index 0dd6af2..bd8e59e 100644
--- a/openstack/orchestration/v1/stacks/requests.go
+++ b/openstack/orchestration/v1/stacks/requests.go
@@ -2,6 +2,7 @@
 
 import (
 	"errors"
+	"strings"
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
@@ -60,6 +61,8 @@
 	Parameters map[string]string
 	// (OPTIONAL) The timeout for stack creation in minutes.
 	Timeout int
+	// (OPTIONAL) A list of tags to assosciate with the Stack
+	Tags []string
 }
 
 // ToStackCreateMap casts a CreateOpts struct to a map.
@@ -97,6 +100,9 @@
 		s["timeout_mins"] = opts.Timeout
 	}
 
+	if opts.Tags != nil {
+		s["tags"] = strings.Join(opts.Tags, ",")
+	}
 	return s, nil
 }
 
@@ -197,12 +203,12 @@
 		s["parameters"] = opts.Parameters
 	}
 
-	if opts.Timeout == 0 {
-		return nil, errors.New("Required field 'Timeout' not provided.")
+	if opts.Timeout != 0 {
+		s["timeout"] = opts.Timeout
 	}
 	s["timeout_mins"] = opts.Timeout
 
-	return map[string]interface{}{"stack": s}, nil
+	return s, nil
 }
 
 // Adopt accepts an AdoptOpts struct and creates a new stack using the resources
@@ -329,6 +335,8 @@
 	Parameters map[string]string
 	// (OPTIONAL) The timeout for stack creation in minutes.
 	Timeout int
+	// (OPTIONAL) A list of tags to assosciate with the Stack
+	Tags []string
 }
 
 // ToStackUpdateMap casts a CreateOpts struct to a map.
@@ -359,6 +367,10 @@
 		s["timeout_mins"] = opts.Timeout
 	}
 
+	if opts.Tags != nil {
+		s["tags"] = strings.Join(opts.Tags, ",")
+	}
+
 	return s, nil
 }
 
diff --git a/openstack/orchestration/v1/stacks/requests_test.go b/openstack/orchestration/v1/stacks/requests_test.go
index 1e32ca2..1606d98 100644
--- a/openstack/orchestration/v1/stacks/requests_test.go
+++ b/openstack/orchestration/v1/stacks/requests_test.go
@@ -215,3 +215,15 @@
 	expected := PreviewExpected
 	th.AssertDeepEquals(t, expected, actual)
 }
+
+func TestAbandonStack(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleAbandonSuccessfully(t, AbandonOutput)
+
+	actual, err := Abandon(fake.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c8").Extract()
+	th.AssertNoErr(t, err)
+
+	expected := AbandonExpected
+	th.AssertDeepEquals(t, expected, actual)
+}
diff --git a/openstack/orchestration/v1/stacks/results.go b/openstack/orchestration/v1/stacks/results.go
index dca06e4..432bc8e 100644
--- a/openstack/orchestration/v1/stacks/results.go
+++ b/openstack/orchestration/v1/stacks/results.go
@@ -69,6 +69,7 @@
 	Name         string             `mapstructure:"stack_name"`
 	Status       string             `mapstructure:"stack_status"`
 	StatusReason string             `mapstructure:"stack_status_reason"`
+	Tags         []string           `mapstructure:"tags"`
 	UpdatedTime  time.Time          `mapstructure:"-"`
 }
 
@@ -81,7 +82,7 @@
 		Stacks []ListedStack `mapstructure:"stacks"`
 	}
 
-	err := mapstructure.Decode(page.(StackPage).Body, &res)
+	err := mapstructure.Decode(casted, &res)
 	if err != nil {
 		return nil, err
 	}
@@ -133,6 +134,7 @@
 	Name                string                   `mapstructure:"stack_name"`
 	Status              string                   `mapstructure:"stack_status"`
 	StatusReason        string                   `mapstructure:"stack_status_reason"`
+	Tags                []string                 `mapstructure:"tags"`
 	TemplateDescription string                   `mapstructure:"template_description"`
 	Timeout             int                      `mapstructure:"timeout_mins"`
 	UpdatedTime         time.Time                `mapstructure:"-"`
@@ -200,21 +202,19 @@
 
 // PreviewedStack represents the result of a Preview operation.
 type PreviewedStack struct {
-	Capabilities        []interface{}            `mapstructure:"capabilities"`
-	CreationTime        time.Time                `mapstructure:"-"`
-	Description         string                   `mapstructure:"description"`
-	DisableRollback     bool                     `mapstructure:"disable_rollback"`
-	ID                  string                   `mapstructure:"id"`
-	Links               []gophercloud.Link       `mapstructure:"links"`
-	Name                string                   `mapstructure:"stack_name"`
-	NotificationTopics  []interface{}            `mapstructure:"notification_topics"`
-	Parameters          map[string]string        `mapstructure:"parameters"`
-	Resources           []map[string]interface{} `mapstructure:"resources"`
-	Status              string                   `mapstructure:"stack_status"`
-	StatusReason        string                   `mapstructure:"stack_status_reason"`
-	TemplateDescription string                   `mapstructure:"template_description"`
-	Timeout             int                      `mapstructure:"timeout_mins"`
-	UpdatedTime         time.Time                `mapstructure:"-"`
+	Capabilities        []interface{}      `mapstructure:"capabilities"`
+	CreationTime        time.Time          `mapstructure:"-"`
+	Description         string             `mapstructure:"description"`
+	DisableRollback     bool               `mapstructure:"disable_rollback"`
+	ID                  string             `mapstructure:"id"`
+	Links               []gophercloud.Link `mapstructure:"links"`
+	Name                string             `mapstructure:"stack_name"`
+	NotificationTopics  []interface{}      `mapstructure:"notification_topics"`
+	Parameters          map[string]string  `mapstructure:"parameters"`
+	Resources           []interface{}      `mapstructure:"resources"`
+	TemplateDescription string             `mapstructure:"template_description"`
+	Timeout             int                `mapstructure:"timeout_mins"`
+	UpdatedTime         time.Time          `mapstructure:"-"`
 }
 
 // PreviewResult represents the result of a Preview operation.
@@ -269,12 +269,16 @@
 
 // AbandonedStack represents the result of an Abandon operation.
 type AbandonedStack struct {
-	Status    string                 `mapstructure:"status"`
-	Name      string                 `mapstructure:"name"`
-	Template  map[string]interface{} `mapstructure:"template"`
-	Action    string                 `mapstructure:"action"`
-	ID        string                 `mapstructure:"id"`
-	Resources map[string]interface{} `mapstructure:"resources"`
+	Status             string                 `mapstructure:"status"`
+	Name               string                 `mapstructure:"name"`
+	Template           map[string]interface{} `mapstructure:"template"`
+	Action             string                 `mapstructure:"action"`
+	ID                 string                 `mapstructure:"id"`
+	Resources          map[string]interface{} `mapstructure:"resources"`
+	Files              map[string]string      `mapstructure:"files"`
+	StackUserProjectID string                 `mapstructure:"stack_user_project_id"`
+	ProjectID          string                 `mapstructure:"project_id"`
+	Environment        map[string]interface{} `mapstructure:"environment"`
 }
 
 // AbandonResult represents the result of an Abandon operation.
diff --git a/openstack/orchestration/v1/stacktemplates/fixtures.go b/openstack/orchestration/v1/stacktemplates/fixtures.go
index 71fa808..fa9b301 100644
--- a/openstack/orchestration/v1/stacktemplates/fixtures.go
+++ b/openstack/orchestration/v1/stacktemplates/fixtures.go
@@ -10,29 +10,7 @@
 )
 
 // GetExpected represents the expected object from a Get request.
-var GetExpected = &Template{
-	Description:         "Simple template to test heat commands",
-	HeatTemplateVersion: "2013-05-23",
-	Parameters: map[string]interface{}{
-		"flavor": map[string]interface{}{
-			"default": "m1.tiny",
-			"type":    "string",
-		},
-	},
-	Resources: map[string]interface{}{
-		"hello_world": map[string]interface{}{
-			"type": "OS::Nova::Server",
-			"properties": map[string]interface{}{
-				"key_name": "heat_key",
-				"flavor": map[string]interface{}{
-					"get_param": "flavor",
-				},
-				"image":     "ad091b52-742f-469e-8f3c-fd81cadf0743",
-				"user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n",
-			},
-		},
-	},
-}
+var GetExpected = "{\n  \"description\": \"Simple template to test heat commands\",\n  \"heat_template_version\": \"2013-05-23\",\n  \"parameters\": {\n    \"flavor\": {\n      \"default\": \"m1.tiny\",\n      \"type\": \"string\"\n    }\n  },\n  \"resources\": {\n    \"hello_world\": {\n      \"properties\": {\n        \"flavor\": {\n          \"get_param\": \"flavor\"\n        },\n        \"image\": \"ad091b52-742f-469e-8f3c-fd81cadf0743\",\n        \"key_name\": \"heat_key\"\n      },\n      \"type\": \"OS::Nova::Server\"\n    }\n  }\n}"
 
 // GetOutput represents the response body from a Get request.
 const GetOutput = `
@@ -53,8 +31,7 @@
         "flavor": {
           "get_param": "flavor"
         },
-        "image": "ad091b52-742f-469e-8f3c-fd81cadf0743",
-        "user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
+        "image": "ad091b52-742f-469e-8f3c-fd81cadf0743"
       }
     }
   }
diff --git a/openstack/orchestration/v1/stacktemplates/requests.go b/openstack/orchestration/v1/stacktemplates/requests.go
index ad1e468..c0cea35 100644
--- a/openstack/orchestration/v1/stacktemplates/requests.go
+++ b/openstack/orchestration/v1/stacktemplates/requests.go
@@ -23,14 +23,14 @@
 
 // ValidateOpts specifies the template validation parameters.
 type ValidateOpts struct {
-	Template    map[string]interface{}
+	Template    string
 	TemplateURL string
 }
 
 // ToStackTemplateValidateMap assembles a request body based on the contents of a ValidateOpts.
 func (opts ValidateOpts) ToStackTemplateValidateMap() (map[string]interface{}, error) {
 	vo := make(map[string]interface{})
-	if opts.Template != nil {
+	if opts.Template != "" {
 		vo["template"] = opts.Template
 		return vo, nil
 	}
diff --git a/openstack/orchestration/v1/stacktemplates/requests_test.go b/openstack/orchestration/v1/stacktemplates/requests_test.go
index d31c4ac..42667c9 100644
--- a/openstack/orchestration/v1/stacktemplates/requests_test.go
+++ b/openstack/orchestration/v1/stacktemplates/requests_test.go
@@ -16,7 +16,7 @@
 	th.AssertNoErr(t, err)
 
 	expected := GetExpected
-	th.AssertDeepEquals(t, expected, actual)
+	th.AssertDeepEquals(t, expected, string(actual))
 }
 
 func TestValidateTemplate(t *testing.T) {
@@ -25,29 +25,29 @@
 	HandleValidateSuccessfully(t, ValidateOutput)
 
 	opts := ValidateOpts{
-		Template: map[string]interface{}{
-			"heat_template_version": "2013-05-23",
-			"description":           "Simple template to test heat commands",
-			"parameters": map[string]interface{}{
-				"flavor": map[string]interface{}{
-					"default": "m1.tiny",
-					"type":    "string",
-				},
-			},
-			"resources": map[string]interface{}{
-				"hello_world": map[string]interface{}{
-					"type": "OS::Nova::Server",
-					"properties": map[string]interface{}{
-						"key_name": "heat_key",
-						"flavor": map[string]interface{}{
-							"get_param": "flavor",
-						},
-						"image":     "ad091b52-742f-469e-8f3c-fd81cadf0743",
-						"user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n",
-					},
-				},
-			},
-		},
+		Template: `{
+		  "heat_template_version": "2013-05-23",
+		  "description": "Simple template to test heat commands",
+		  "parameters": {
+		    "flavor": {
+		      "default": "m1.tiny",
+		      "type": "string"
+		    }
+		  },
+		  "resources": {
+		    "hello_world": {
+		      "type": "OS::Nova::Server",
+		      "properties": {
+		        "key_name": "heat_key",
+		        "flavor": {
+		          "get_param": "flavor"
+		        },
+		        "image": "ad091b52-742f-469e-8f3c-fd81cadf0743",
+		        "user_data": "#!/bin/bash -xv\necho \"hello world\" &gt; /root/hello-world.txt\n"
+		      }
+		    }
+		  }
+		}`,
 	}
 	actual, err := Validate(fake.ServiceClient(), opts).Extract()
 	th.AssertNoErr(t, err)
diff --git a/openstack/orchestration/v1/stacktemplates/results.go b/openstack/orchestration/v1/stacktemplates/results.go
index ac2f24b..4e9ba5a 100644
--- a/openstack/orchestration/v1/stacktemplates/results.go
+++ b/openstack/orchestration/v1/stacktemplates/results.go
@@ -1,42 +1,33 @@
 package stacktemplates
 
 import (
+	"encoding/json"
 	"github.com/mitchellh/mapstructure"
 	"github.com/rackspace/gophercloud"
 )
 
-// Template represents a stack template.
-type Template struct {
-	Description         string                 `mapstructure:"description"`
-	HeatTemplateVersion string                 `mapstructure:"heat_template_version"`
-	Parameters          map[string]interface{} `mapstructure:"parameters"`
-	Resources           map[string]interface{} `mapstructure:"resources"`
-}
-
 // GetResult represents the result of a Get operation.
 type GetResult struct {
 	gophercloud.Result
 }
 
-// Extract returns a pointer to a Template object and is called after a
-// Get operation.
-func (r GetResult) Extract() (*Template, error) {
+// Extract returns the JSON template and is called after a Get operation.
+func (r GetResult) Extract() ([]byte, error) {
 	if r.Err != nil {
 		return nil, r.Err
 	}
-
-	var res Template
-	if err := mapstructure.Decode(r.Body, &res); err != nil {
+	template, err := json.MarshalIndent(r.Body, "", "  ")
+	if err != nil {
 		return nil, err
 	}
-
-	return &res, nil
+	return template, nil
 }
 
 // ValidatedTemplate represents the parsed object returned from a Validate request.
 type ValidatedTemplate struct {
-	Description string
-	Parameters  map[string]interface{}
+	Description     string                 `mapstructure:"Description"`
+	Parameters      map[string]interface{} `mapstructure:"Parameters"`
+	ParameterGroups map[string]interface{} `mapstructure:"ParameterGroups"`
 }
 
 // ValidateResult represents the result of a Validate operation.