فهرست منبع

Merged with master, resolved conflicts

utkarshcmu 10 سال پیش
والد
کامیت
9498c78576
100فایلهای تغییر یافته به همراه12768 افزوده شده و 1627 حذف شده
  1. 1 0
      .gitignore
  2. 50 3
      CHANGELOG.md
  3. 33 22
      Godeps/Godeps.json
  4. 4 7
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
  5. 32 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go
  6. 27 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
  7. 29 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go
  8. 70 35
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
  9. 95 21
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go
  10. 89 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
  11. 120 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/client.go
  12. 4 8
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
  13. 12 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
  14. 48 17
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go
  15. 8 2
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go
  16. 17 14
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
  17. 11 5
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go
  18. 1 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
  19. 6 6
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go
  20. 34 29
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
  21. 14 16
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go
  22. 4 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/example.ini
  23. 16 12
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
  24. 12 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go
  25. 40 35
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
  26. 4 7
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go
  27. 64 27
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
  28. 4 4
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
  29. 8 7
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go
  30. 49 82
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
  31. 2 2
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go
  32. 28 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go
  33. 2 2
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go
  34. 26 95
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go
  35. 104 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
  36. 160 12
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go
  37. 42 9
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go
  38. 10 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go
  39. 0 133
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go
  40. 0 15
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go
  41. 105 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session.go
  42. 20 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session_test.go
  43. 1 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go
  44. 1 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go
  45. 38 4
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go
  46. 8 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json
  47. 8 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go
  48. 20 7
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints_test.go
  49. 1 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go
  50. 2 2
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build_bench_test.go
  51. 316 147
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build_test.go
  52. 433 139
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/unmarshal_test.go
  53. 1 1
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/build.go
  54. 539 196
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/build_test.go
  55. 2 2
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
  56. 620 228
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_test.go
  57. 3 4
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/functional_test.go
  58. 8 8
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
  59. 13 8
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/v4_test.go
  60. 136 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/waiter/waiter.go
  61. 391 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/waiter/waiter_test.go
  62. 3 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/api.go
  63. 2 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go
  64. 0 15
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface_test.go
  65. 12 11
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/examples_test.go
  66. 47 24
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/service.go
  67. 58 24
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go
  68. 18 20
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go
  69. 4 5
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go
  70. 4 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go
  71. 0 15
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface_test.go
  72. 112 111
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go
  73. 47 24
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go
  74. 761 0
      Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/waiters.go
  75. 4 0
      Godeps/_workspace/src/github.com/go-ini/ini/.gitignore
  76. 191 0
      Godeps/_workspace/src/github.com/go-ini/ini/LICENSE
  77. 560 0
      Godeps/_workspace/src/github.com/go-ini/ini/README.md
  78. 547 0
      Godeps/_workspace/src/github.com/go-ini/ini/README_ZH.md
  79. 1226 0
      Godeps/_workspace/src/github.com/go-ini/ini/ini.go
  80. 512 0
      Godeps/_workspace/src/github.com/go-ini/ini/ini_test.go
  81. 350 0
      Godeps/_workspace/src/github.com/go-ini/ini/struct.go
  82. 239 0
      Godeps/_workspace/src/github.com/go-ini/ini/struct_test.go
  83. 2 0
      Godeps/_workspace/src/github.com/go-ini/ini/testdata/conf.ini
  84. 4 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/.gitignore
  85. 9 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/.travis.yml
  86. 13 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/LICENSE
  87. 44 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/Makefile
  88. 7 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/README.md
  89. 12 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/api.go
  90. 16 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/astnodetype_string.go
  91. 96 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/basic.json
  92. 257 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/boolean.json
  93. 25 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/current.json
  94. 46 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/escape.json
  95. 468 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/filters.json
  96. 825 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/functions.json
  97. 1377 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/identifiers.json
  98. 346 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/indices.json
  99. 185 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/literal.json
  100. 393 0
      Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/multiselect.json

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 node_modules
+npm-debug.log
 coverage/
 .aws-config.json
 awsconfig

+ 50 - 3
CHANGELOG.md

@@ -1,4 +1,51 @@
-# 2.5 (unreleased)
+# 3.0.0 (unrelased master branch)
+
+
+### Breaking changes
+**InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds. Can easily be installed via improved plugin system, closes #3523
+**KairosDB** The data source is no longer included in default builds. Can easily be installed via improved plugin system, closes #3524
+
+# 2.6.1 (unrelased, 2.6.x branch)
+
+### New Features
+* **Elasticsearch**: Support for derivative unit option, closes [#3512](https://github.com/grafana/grafana/issues/3512)
+
+# 2.6.0 (2015-12-14)
+
+### New Features
+* **Elasticsearch**: Support for pipeline aggregations Moving average and derivative, closes [#2715](https://github.com/grafana/grafana/issues/2715)
+* **Elasticsearch**: Support for inline script and missing options for metrics, closes [#3500](https://github.com/grafana/grafana/issues/3500)
+* **Syslog**: Support for syslog logging, closes [#3161](https://github.com/grafana/grafana/pull/3161)
+* **Timepicker**: Always show refresh button even with refresh rate, closes [#3498](https://github.com/grafana/grafana/pull/3498)
+* **Login**: Make it possible to change the login hint on the login page, closes [#2571](https://github.com/grafana/grafana/pull/2571)
+
+### Bug Fixes
+* **metric editors**: Fix for clicking typeahead auto dropdown option, fixes [#3428](https://github.com/grafana/grafana/issues/3428)
+* **influxdb**: Fixed issue showing Group By label only on first query, fixes [#3453](https://github.com/grafana/grafana/issues/3453)
+* **logging**: Add more verbose info logging for http reqeusts, closes [#3405](https://github.com/grafana/grafana/pull/3405)
+
+# 2.6.0-Beta1 (2015-12-04)
+
+### New Table Panel
+* **table**:  New powerful and flexible table panel, closes [#215](https://github.com/grafana/grafana/issues/215)
+
+### Enhancements
+* **CloudWatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080)
+* **Elasticsearch**: Support for dynamic daily indices for annotations, closes [#3061](https://github.com/grafana/grafana/issues/3061)
+* **Elasticsearch**: Support for setting min_doc_count for date histogram, closes [#3416](https://github.com/grafana/grafana/issues/3416)
+* **Graph Panel**: Option to hide series with all zeroes from legend and tooltip, closes [#1381](https://github.com/grafana/grafana/issues/1381), [#3336](https://github.com/grafana/grafana/issues/3336)
+
+### Bug Fixes
+* **cloudwatch**: fix for handling of period for long time ranges, fixes [#3086](https://github.com/grafana/grafana/issues/3086)
+* **dashboard**: fix for collapse row by clicking on row title, fixes [#3065](https://github.com/grafana/grafana/issues/3065)
+* **influxdb**: fix for relative time ranges `last x months` and `last x years`, fixes [#3067](https://github.com/grafana/grafana/issues/3067)
+* **graph**: layout fix for color picker when right side legend was enabled, fixes [#3093](https://github.com/grafana/grafana/issues/3093)
+* **elasticsearch**: disabling elastic query (via eye) caused error, fixes [#3300](https://github.com/grafana/grafana/issues/3300)
+
+### Breaking changes
+* **elasticsearch**: Manual json edited queries are not supported any more (They very barely worked in 2.5)
+
+# 2.5 (2015-10-28)
 
 **New Feature: Mix data sources**
 - A built in data source is now available named `-- Mixed --`, When picked in the metrics tab,
@@ -11,12 +58,12 @@ it allows you to add queries of differnet data source types & instances to the s
 
 **New Feature: New and much improved time picker**
 - Support for quick ranges like `Today`, `This day last week`, `This week`, `The day so far`, etc.
-- Muck improved UI and improved support for UTC, [Issue #2761](https://github.com/grafana/grafana/issues/2761) for more info.
+- Improved UI and improved support for UTC, [Issue #2761](https://github.com/grafana/grafana/issues/2761) for more info.
 
 **User Onboarding**
 - Org admin can now send email invites (or invite links) to people who are not yet Grafana users
 - Sign up flow now supports email verification (if enabled)
-- See [Issue #2353](https://github.com/grafana/grafana/issues/2354) for more info.
+- See [Issue #2353](https://github.com/grafana/grafana/issues/2353) for more info.
 
 **Other new Features && Enhancements**
 - [Pull  #2720](https://github.com/grafana/grafana/pull/2720). Admin: Initial basic quota support (per Org)

+ 33 - 22
Godeps/Godeps.json

@@ -20,53 +20,63 @@
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/aws",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
+		},
+		{
+			"ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatch",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
-			"Comment": "v0.9.16-3-g4944a94",
-			"Rev": "4944a94a3b092d1dad8a964415700a70f55e580a"
+			"Comment": "v1.0.0",
+			"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
 		},
 		{
 			"ImportPath": "github.com/davecgh/go-spew/spew",
 			"Rev": "2df174808ee097f90d259e432cc04442cf60be21"
 		},
+		{
+			"ImportPath": "github.com/go-ini/ini",
+			"Comment": "v0-48-g060d7da",
+			"Rev": "060d7da055ba6ec5ea7a31f116332fe5efa04ce0"
+		},
 		{
 			"ImportPath": "github.com/go-ldap/ldap",
 			"Comment": "v1-19-g83e6542",
@@ -90,6 +100,11 @@
 			"ImportPath": "github.com/gosimple/slug",
 			"Rev": "8d258463b4459f161f51d6a357edacd3eef9d663"
 		},
+		{
+			"ImportPath": "github.com/jmespath/go-jmespath",
+			"Comment": "0.2.2",
+			"Rev": "3433f3ea46d9f8019119e7dd41274e112a2359a9"
+		},
 		{
 			"ImportPath": "github.com/jtolds/gls",
 			"Rev": "f1ac7f4f24f50328e6bc838ca4437d1612a0243c"
@@ -124,10 +139,6 @@
 			"ImportPath": "github.com/streadway/amqp",
 			"Rev": "150b7f24d6ad507e6026c13d85ce1f1391ac7400"
 		},
-		{
-			"ImportPath": "github.com/vaughan0/go-ini",
-			"Rev": "a98ad7ee00ec53921f08832bc06ecf7fd600e6a1"
-		},
 		{
 			"ImportPath": "golang.org/x/net/context",
 			"Rev": "972f0c5fbe4ae29e666c3f78c3ed42ae7a448b0a"

+ 4 - 7
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy.go

@@ -57,16 +57,13 @@ func rcopy(dst, src reflect.Value, root bool) {
 			}
 		}
 	case reflect.Struct:
-		if !root {
-			dst.Set(reflect.New(src.Type()).Elem())
-		}
-
 		t := dst.Type()
 		for i := 0; i < t.NumField(); i++ {
 			name := t.Field(i).Name
-			srcval := src.FieldByName(name)
-			if srcval.IsValid() {
-				rcopy(dst.FieldByName(name), srcval, false)
+			srcVal := src.FieldByName(name)
+			dstVal := dst.FieldByName(name)
+			if srcVal.IsValid() && dstVal.CanSet() {
+				rcopy(dstVal, srcVal, false)
 			}
 		}
 	case reflect.Slice:

+ 32 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go

@@ -77,6 +77,28 @@ func TestCopy(t *testing.T) {
 	assert.NotEqual(t, f2.C, f1.C)
 }
 
+func TestCopyNestedWithUnexported(t *testing.T) {
+	type Bar struct {
+		a int
+		B int
+	}
+	type Foo struct {
+		A string
+		B Bar
+	}
+
+	f1 := &Foo{A: "string", B: Bar{a: 1, B: 2}}
+
+	var f2 Foo
+	awsutil.Copy(&f2, f1)
+
+	// Values match
+	assert.Equal(t, f2.A, f1.A)
+	assert.NotEqual(t, f2.B, f1.B)
+	assert.NotEqual(t, f2.B.a, f1.B.a)
+	assert.Equal(t, f2.B.B, f2.B.B)
+}
+
 func TestCopyIgnoreNilMembers(t *testing.T) {
 	type Foo struct {
 		A *string
@@ -136,6 +158,8 @@ func TestCopyDifferentStructs(t *testing.T) {
 		C                map[string]*int
 		SrcUnique        string
 		SameNameDiffType int
+		unexportedPtr    *int
+		ExportedPtr      *int
 	}
 	type DstFoo struct {
 		A                int
@@ -143,6 +167,8 @@ func TestCopyDifferentStructs(t *testing.T) {
 		C                map[string]*int
 		DstUnique        int
 		SameNameDiffType string
+		unexportedPtr    *int
+		ExportedPtr      *int
 	}
 
 	// Create the initial value
@@ -159,6 +185,8 @@ func TestCopyDifferentStructs(t *testing.T) {
 		},
 		SrcUnique:        "unique",
 		SameNameDiffType: 1,
+		unexportedPtr:    &int1,
+		ExportedPtr:      &int2,
 	}
 
 	// Do the copy
@@ -173,6 +201,10 @@ func TestCopyDifferentStructs(t *testing.T) {
 	assert.Equal(t, 1, f1.SameNameDiffType)
 	assert.Equal(t, 0, f2.DstUnique)
 	assert.Equal(t, "", f2.SameNameDiffType)
+	assert.Equal(t, int1, *f1.unexportedPtr)
+	assert.Nil(t, f2.unexportedPtr)
+	assert.Equal(t, int2, *f1.ExportedPtr)
+	assert.Equal(t, int2, *f2.ExportedPtr)
 }
 
 func ExampleCopyOf() {

+ 27 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal.go

@@ -0,0 +1,27 @@
+package awsutil
+
+import (
+	"reflect"
+)
+
+// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
+// In addition to this, this method will also dereference the input values if
+// possible so the DeepEqual performed will not fail if one parameter is a
+// pointer and the other is not.
+//
+// DeepEqual will not perform indirection of nested values of the input parameters.
+func DeepEqual(a, b interface{}) bool {
+	ra := reflect.Indirect(reflect.ValueOf(a))
+	rb := reflect.Indirect(reflect.ValueOf(b))
+
+	if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
+		// If the elements are both nil, and of the same type the are equal
+		// If they are of different types they are not equal
+		return reflect.TypeOf(a) == reflect.TypeOf(b)
+	} else if raValid != rbValid {
+		// Both values must be valid to be equal
+		return false
+	}
+
+	return reflect.DeepEqual(ra.Interface(), rb.Interface())
+}

+ 29 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go

@@ -0,0 +1,29 @@
+package awsutil_test
+
+import (
+	"testing"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDeepEqual(t *testing.T) {
+	cases := []struct {
+		a, b  interface{}
+		equal bool
+	}{
+		{"a", "a", true},
+		{"a", "b", false},
+		{"a", aws.String(""), false},
+		{"a", nil, false},
+		{"a", aws.String("a"), true},
+		{(*bool)(nil), (*bool)(nil), true},
+		{(*bool)(nil), (*string)(nil), false},
+		{nil, nil, true},
+	}
+
+	for i, c := range cases {
+		assert.Equal(t, c.equal, awsutil.DeepEqual(c.a, c.b), "%d, a:%v b:%v, %t", i, c.a, c.b, c.equal)
+	}
+}

+ 70 - 35
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go

@@ -5,18 +5,20 @@ import (
 	"regexp"
 	"strconv"
 	"strings"
+
+	"github.com/jmespath/go-jmespath"
 )
 
 var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
 
 // rValuesAtPath returns a slice of values found in value v. The values
 // in v are explored recursively so all nested values are collected.
-func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool) []reflect.Value {
+func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
 	pathparts := strings.Split(path, "||")
 	if len(pathparts) > 1 {
 		for _, pathpart := range pathparts {
-			vals := rValuesAtPath(v, pathpart, create, caseSensitive)
-			if vals != nil && len(vals) > 0 {
+			vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
+			if len(vals) > 0 {
 				return vals
 			}
 		}
@@ -74,7 +76,16 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool)
 				return false
 			})
 
-			if create && value.Kind() == reflect.Ptr && value.IsNil() {
+			if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
+				if !value.IsNil() {
+					value.Set(reflect.Zero(value.Type()))
+				}
+				return []reflect.Value{value}
+			}
+
+			if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
+				// TODO if the value is the terminus it should not be created
+				// if the value to be set to its position is nil.
 				value.Set(reflect.New(value.Type().Elem()))
 				value = value.Elem()
 			} else {
@@ -82,7 +93,7 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool)
 			}
 
 			if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
-				if !create && value.IsNil() {
+				if !createPath && value.IsNil() {
 					value = reflect.ValueOf(nil)
 				}
 			}
@@ -114,7 +125,7 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool)
 				// pull out index
 				i := int(*index)
 				if i >= value.Len() { // check out of bounds
-					if create {
+					if createPath {
 						// TODO resize slice
 					} else {
 						continue
@@ -125,7 +136,7 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool)
 				value = reflect.Indirect(value.Index(i))
 
 				if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
-					if !create && value.IsNil() {
+					if !createPath && value.IsNil() {
 						value = reflect.ValueOf(nil)
 					}
 				}
@@ -142,46 +153,70 @@ func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool)
 	return values
 }
 
-// ValuesAtPath returns a list of objects at the lexical path inside of a structure
-func ValuesAtPath(i interface{}, path string) []interface{} {
-	if rvals := rValuesAtPath(i, path, false, true); rvals != nil {
-		vals := make([]interface{}, len(rvals))
-		for i, rval := range rvals {
-			vals[i] = rval.Interface()
-		}
-		return vals
+// ValuesAtPath returns a list of values at the case insensitive lexical
+// path inside of a structure.
+func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
+	result, err := jmespath.Search(path, i)
+	if err != nil {
+		return nil, err
 	}
-	return nil
-}
 
-// ValuesAtAnyPath returns a list of objects at the case-insensitive lexical
-// path inside of a structure
-func ValuesAtAnyPath(i interface{}, path string) []interface{} {
-	if rvals := rValuesAtPath(i, path, false, false); rvals != nil {
-		vals := make([]interface{}, len(rvals))
-		for i, rval := range rvals {
-			vals[i] = rval.Interface()
+	v := reflect.ValueOf(result)
+	if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
+		return nil, nil
+	}
+	if s, ok := result.([]interface{}); ok {
+		return s, err
+	}
+	if v.Kind() == reflect.Map && v.Len() == 0 {
+		return nil, nil
+	}
+	if v.Kind() == reflect.Slice {
+		out := make([]interface{}, v.Len())
+		for i := 0; i < v.Len(); i++ {
+			out[i] = v.Index(i).Interface()
 		}
-		return vals
+		return out, nil
 	}
-	return nil
+
+	return []interface{}{result}, nil
 }
 
-// SetValueAtPath sets an object at the lexical path inside of a structure
+// SetValueAtPath sets a value at the case insensitive lexical path inside
+// of a structure.
 func SetValueAtPath(i interface{}, path string, v interface{}) {
-	if rvals := rValuesAtPath(i, path, true, true); rvals != nil {
+	if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
 		for _, rval := range rvals {
-			rval.Set(reflect.ValueOf(v))
+			if rval.Kind() == reflect.Ptr && rval.IsNil() {
+				continue
+			}
+			setValue(rval, v)
 		}
 	}
 }
 
-// SetValueAtAnyPath sets an object at the case insensitive lexical path inside
-// of a structure
-func SetValueAtAnyPath(i interface{}, path string, v interface{}) {
-	if rvals := rValuesAtPath(i, path, true, false); rvals != nil {
-		for _, rval := range rvals {
-			rval.Set(reflect.ValueOf(v))
+func setValue(dstVal reflect.Value, src interface{}) {
+	if dstVal.Kind() == reflect.Ptr {
+		dstVal = reflect.Indirect(dstVal)
+	}
+	srcVal := reflect.ValueOf(src)
+
+	if !srcVal.IsValid() { // src is literal nil
+		if dstVal.CanAddr() {
+			// Convert to pointer so that pointer's value can be nil'ed
+			//                     dstVal = dstVal.Addr()
+		}
+		dstVal.Set(reflect.Zero(dstVal.Type()))
+
+	} else if srcVal.Kind() == reflect.Ptr {
+		if srcVal.IsNil() {
+			srcVal = reflect.Zero(dstVal.Type())
+		} else {
+			srcVal = reflect.ValueOf(src).Elem()
 		}
+		dstVal.Set(srcVal)
+	} else {
+		dstVal.Set(srcVal)
 	}
+
 }

+ 95 - 21
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go

@@ -13,6 +13,7 @@ type Struct struct {
 	B *Struct
 	D *Struct
 	C string
+	E map[string]string
 }
 
 var data = Struct{
@@ -21,30 +22,69 @@ var data = Struct{
 	B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
 	C: "initial",
 }
+var data2 = Struct{A: []Struct{
+	{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
+	{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
+}}
 
 func TestValueAtPathSuccess(t *testing.T) {
-	assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "C"))
-	assert.Equal(t, []interface{}{"value1"}, awsutil.ValuesAtPath(data, "A[0].C"))
-	assert.Equal(t, []interface{}{"value2"}, awsutil.ValuesAtPath(data, "A[1].C"))
-	assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[2].C"))
-	assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtAnyPath(data, "a[2].c"))
-	assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[-1].C"))
-	assert.Equal(t, []interface{}{"value1", "value2", "value3"}, awsutil.ValuesAtPath(data, "A[].C"))
-	assert.Equal(t, []interface{}{"terminal"}, awsutil.ValuesAtPath(data, "B . B . C"))
-	assert.Equal(t, []interface{}{"terminal", "terminal2"}, awsutil.ValuesAtPath(data, "B.*.C"))
-	assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "A.D.X || C"))
+	var testCases = []struct {
+		expect []interface{}
+		data   interface{}
+		path   string
+	}{
+		{[]interface{}{"initial"}, data, "C"},
+		{[]interface{}{"value1"}, data, "A[0].C"},
+		{[]interface{}{"value2"}, data, "A[1].C"},
+		{[]interface{}{"value3"}, data, "A[2].C"},
+		{[]interface{}{"value3"}, data, "a[2].c"},
+		{[]interface{}{"value3"}, data, "A[-1].C"},
+		{[]interface{}{"value1", "value2", "value3"}, data, "A[].C"},
+		{[]interface{}{"terminal"}, data, "B . B . C"},
+		{[]interface{}{"initial"}, data, "A.D.X || C"},
+		{[]interface{}{"initial"}, data, "A[0].B || C"},
+		{[]interface{}{
+			Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
+			Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
+		}, data2, "A"},
+	}
+	for i, c := range testCases {
+		v, err := awsutil.ValuesAtPath(c.data, c.path)
+		assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
+		assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
+	}
 }
 
 func TestValueAtPathFailure(t *testing.T) {
-	assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "C.x"))
-	assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, ".x"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "X.Y.Z"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[100].C"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[3].C"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "B.B.C.Z"))
-	assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "z[-1].C"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(nil, "A.B.C"))
-	assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(Struct{}, "A"))
+	var testCases = []struct {
+		expect      []interface{}
+		errContains string
+		data        interface{}
+		path        string
+	}{
+		{nil, "", data, "C.x"},
+		{nil, "SyntaxError: Invalid token: tDot", data, ".x"},
+		{nil, "", data, "X.Y.Z"},
+		{nil, "", data, "A[100].C"},
+		{nil, "", data, "A[3].C"},
+		{nil, "", data, "B.B.C.Z"},
+		{nil, "", data, "z[-1].C"},
+		{nil, "", nil, "A.B.C"},
+		{[]interface{}{}, "", Struct{}, "A"},
+		{nil, "", data, "A[0].B.C"},
+		{nil, "", data, "D"},
+	}
+
+	for i, c := range testCases {
+		v, err := awsutil.ValuesAtPath(c.data, c.path)
+		if c.errContains != "" {
+			assert.Contains(t, err.Error(), c.errContains, "case %d, expected error, %s", i, c.path)
+			continue
+		} else {
+			assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
+		}
+		assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
+	}
 }
 
 func TestSetValueAtPathSuccess(t *testing.T) {
@@ -61,8 +101,42 @@ func TestSetValueAtPathSuccess(t *testing.T) {
 	assert.Equal(t, "test0", s.B.D.C)
 
 	var s2 Struct
-	awsutil.SetValueAtAnyPath(&s2, "b.b.c", "test0")
+	awsutil.SetValueAtPath(&s2, "b.b.c", "test0")
 	assert.Equal(t, "test0", s2.B.B.C)
-	awsutil.SetValueAtAnyPath(&s2, "A", []Struct{{}})
+	awsutil.SetValueAtPath(&s2, "A", []Struct{{}})
 	assert.Equal(t, []Struct{{}}, s2.A)
+
+	str := "foo"
+
+	s3 := Struct{}
+	awsutil.SetValueAtPath(&s3, "b.b.c", str)
+	assert.Equal(t, "foo", s3.B.B.C)
+
+	s3 = Struct{B: &Struct{B: &Struct{C: str}}}
+	awsutil.SetValueAtPath(&s3, "b.b.c", nil)
+	assert.Equal(t, "", s3.B.B.C)
+
+	s3 = Struct{}
+	awsutil.SetValueAtPath(&s3, "b.b.c", nil)
+	assert.Equal(t, "", s3.B.B.C)
+
+	s3 = Struct{}
+	awsutil.SetValueAtPath(&s3, "b.b.c", &str)
+	assert.Equal(t, "foo", s3.B.B.C)
+
+	var s4 struct{ Name *string }
+	awsutil.SetValueAtPath(&s4, "Name", str)
+	assert.Equal(t, str, *s4.Name)
+
+	s4 = struct{ Name *string }{}
+	awsutil.SetValueAtPath(&s4, "Name", nil)
+	assert.Equal(t, (*string)(nil), s4.Name)
+
+	s4 = struct{ Name *string }{Name: &str}
+	awsutil.SetValueAtPath(&s4, "Name", nil)
+	assert.Equal(t, (*string)(nil), s4.Name)
+
+	s4 = struct{ Name *string }{}
+	awsutil.SetValueAtPath(&s4, "Name", &str)
+	assert.Equal(t, str, *s4.Name)
 }

+ 89 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go

@@ -0,0 +1,89 @@
+package awsutil
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// StringValue returns the string representation of a value.
+func StringValue(i interface{}) string {
+	var buf bytes.Buffer
+	stringValue(reflect.ValueOf(i), 0, &buf)
+	return buf.String()
+}
+
+func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
+	for v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+
+	switch v.Kind() {
+	case reflect.Struct:
+		buf.WriteString("{\n")
+
+		names := []string{}
+		for i := 0; i < v.Type().NumField(); i++ {
+			name := v.Type().Field(i).Name
+			f := v.Field(i)
+			if name[0:1] == strings.ToLower(name[0:1]) {
+				continue // ignore unexported fields
+			}
+			if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
+				continue // ignore unset fields
+			}
+			names = append(names, name)
+		}
+
+		for i, n := range names {
+			val := v.FieldByName(n)
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(n + ": ")
+			stringValue(val, indent+2, buf)
+
+			if i < len(names)-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	case reflect.Slice:
+		nl, id, id2 := "", "", ""
+		if v.Len() > 3 {
+			nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
+		}
+		buf.WriteString("[" + nl)
+		for i := 0; i < v.Len(); i++ {
+			buf.WriteString(id2)
+			stringValue(v.Index(i), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString("," + nl)
+			}
+		}
+
+		buf.WriteString(nl + id + "]")
+	case reflect.Map:
+		buf.WriteString("{\n")
+
+		for i, k := range v.MapKeys() {
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(k.String() + ": ")
+			stringValue(v.MapIndex(k), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	default:
+		format := "%v"
+		switch v.Interface().(type) {
+		case string:
+			format = "%q"
+		}
+		fmt.Fprintf(buf, format, v.Interface())
+	}
+}

+ 120 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/client.go

@@ -0,0 +1,120 @@
+package client
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net/http/httputil"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// A Config provides configuration to a service client instance.
+type Config struct {
+	Config                  *aws.Config
+	Handlers                request.Handlers
+	Endpoint, SigningRegion string
+}
+
+// ConfigProvider provides a generic way for a service client to receive
+// the ClientConfig without circular dependencies.
+type ConfigProvider interface {
+	ClientConfig(serviceName string, cfgs ...*aws.Config) Config
+}
+
+// A Client implements the base client request and response handling
+// used by all service clients.
+type Client struct {
+	request.Retryer
+	metadata.ClientInfo
+
+	Config   aws.Config
+	Handlers request.Handlers
+}
+
+// New will return a pointer to a new initialized service client.
+func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
+	svc := &Client{
+		Config:     cfg,
+		ClientInfo: info,
+		Handlers:   handlers,
+	}
+
+	switch retryer, ok := cfg.Retryer.(request.Retryer); {
+	case ok:
+		svc.Retryer = retryer
+	case cfg.Retryer != nil && cfg.Logger != nil:
+		s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
+		cfg.Logger.Log(s)
+		fallthrough
+	default:
+		maxRetries := aws.IntValue(cfg.MaxRetries)
+		if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
+			maxRetries = 3
+		}
+		svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
+	}
+
+	svc.AddDebugHandlers()
+
+	for _, option := range options {
+		option(svc)
+	}
+
+	return svc
+}
+
+// NewRequest returns a new Request pointer for the service API
+// operation and parameters.
+func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
+	return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
+}
+
+// AddDebugHandlers injects debug logging handlers into the service to log request
+// debug information.
+func (c *Client) AddDebugHandlers() {
+	if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
+		return
+	}
+
+	c.Handlers.Send.PushFront(logRequest)
+	c.Handlers.Send.PushBack(logResponse)
+}
+
+const logReqMsg = `DEBUG: Request %s/%s Details:
+---[ REQUEST POST-SIGN ]-----------------------------
+%s
+-----------------------------------------------------`
+
+func logRequest(r *request.Request) {
+	logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
+	dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
+
+	if logBody {
+		// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
+		// Body as a NoOpCloser and will not be reset after read by the HTTP
+		// client reader.
+		r.Body.Seek(r.BodyStart, 0)
+		r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
+	}
+
+	r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
+}
+
+const logRespMsg = `DEBUG: Response %s/%s Details:
+---[ RESPONSE ]--------------------------------------
+%s
+-----------------------------------------------------`
+
+func logResponse(r *request.Request) {
+	var msg = "no reponse data"
+	if r.HTTPResponse != nil {
+		logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
+		dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
+		msg = string(dumpedBody)
+	} else if r.Error != nil {
+		msg = r.Error.Error()
+	}
+	r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg))
+}

+ 4 - 8
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/default_retryer.go → Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/default_retryer.go

@@ -1,11 +1,10 @@
-package service
+package client
 
 import (
 	"math"
 	"math/rand"
 	"time"
 
-	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/request"
 )
 
@@ -22,16 +21,13 @@ import (
 //    // This implementation always has 100 max retries
 //    func (d retryer) MaxRetries() uint { return 100 }
 type DefaultRetryer struct {
-	*Service
+	NumMaxRetries int
 }
 
 // MaxRetries returns the number of maximum returns the service will use to make
 // an individual API request.
-func (d DefaultRetryer) MaxRetries() uint {
-	if aws.IntValue(d.Service.Config.MaxRetries) < 0 {
-		return d.DefaultMaxRetries
-	}
-	return uint(aws.IntValue(d.Service.Config.MaxRetries))
+func (d DefaultRetryer) MaxRetries() int {
+	return d.NumMaxRetries
 }
 
 // RetryRules returns the delay duration before retrying this request again

+ 12 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go

@@ -0,0 +1,12 @@
+package metadata
+
+// ClientInfo wraps immutable data from the client.Client structure.
+type ClientInfo struct {
+	ServiceName   string
+	APIVersion    string
+	Endpoint      string
+	SigningName   string
+	SigningRegion string
+	JSONVersion   string
+	TargetPrefix  string
+}

+ 48 - 17
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config.go

@@ -7,15 +7,20 @@ import (
 	"github.com/aws/aws-sdk-go/aws/credentials"
 )
 
-// DefaultRetries is the default number of retries for a service. The value of
-// -1 indicates that the service specific retry default will be used.
-const DefaultRetries = -1
+// UseServiceDefaultRetries instructs the config to use the service's own default
+// number of retries. This will be the default action if Config.MaxRetries
+// is nil also.
+const UseServiceDefaultRetries = -1
+
+// RequestRetryer is an alias for a type that implements the request.Retryer interface.
+type RequestRetryer interface{}
 
 // A Config provides service configuration for service clients. By default,
 // all clients will use the {defaults.DefaultConfig} structure.
 type Config struct {
 	// The credentials object to use when signing requests. Defaults to
-	// {defaults.DefaultChainCredentials}.
+	// a chain of credential providers to search for credentials in environment
+	// variables, shared credential file, and EC2 Instance Roles.
 	Credentials *credentials.Credentials
 
 	// An optional endpoint URL (hostname only or fully qualified URI)
@@ -57,6 +62,21 @@ type Config struct {
 	// configuration.
 	MaxRetries *int
 
+	// Retryer guides how HTTP requests should be retried in case of recoverable failures.
+	//
+	// When nil or the value does not implement the request.Retryer interface,
+	// the request.DefaultRetryer will be used.
+	//
+	// When both Retryer and MaxRetries are non-nil, the former is used and
+	// the latter ignored.
+	//
+	// To set the Retryer field in a type-safe manner and with chaining, use
+	// the request.WithRetryer helper function:
+	//
+	//   cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
+	//
+	Retryer RequestRetryer
+
 	// Disables semantic parameter validation, which validates input for missing
 	// required fields and/or other semantic request input errors.
 	DisableParamValidation *bool
@@ -171,15 +191,17 @@ func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
 	return c
 }
 
-// Merge returns a new Config with the other Config's attribute values merged into
-// this Config. If the other Config's attribute is nil it will not be merged into
-// the new Config to be returned.
-func (c Config) Merge(other *Config) *Config {
-	if other == nil {
-		return &c
+// MergeIn merges the passed in configs into the existing config object.
+func (c *Config) MergeIn(cfgs ...*Config) {
+	for _, other := range cfgs {
+		mergeInConfig(c, other)
 	}
+}
 
-	dst := c
+func mergeInConfig(dst *Config, other *Config) {
+	if other == nil {
+		return
+	}
 
 	if other.Credentials != nil {
 		dst.Credentials = other.Credentials
@@ -213,6 +235,10 @@ func (c Config) Merge(other *Config) *Config {
 		dst.MaxRetries = other.MaxRetries
 	}
 
+	if other.Retryer != nil {
+		dst.Retryer = other.Retryer
+	}
+
 	if other.DisableParamValidation != nil {
 		dst.DisableParamValidation = other.DisableParamValidation
 	}
@@ -228,12 +254,17 @@ func (c Config) Merge(other *Config) *Config {
 	if other.SleepDelay != nil {
 		dst.SleepDelay = other.SleepDelay
 	}
-
-	return &dst
 }
 
-// Copy will return a shallow copy of the Config object.
-func (c Config) Copy() *Config {
-	dst := c
-	return &dst
+// Copy will return a shallow copy of the Config object. If any additional
+// configurations are provided they will be merged into the new config returned.
+func (c *Config) Copy(cfgs ...*Config) *Config {
+	dst := &Config{}
+	dst.MergeIn(c)
+
+	for _, cfg := range cfgs {
+		dst.MergeIn(cfg)
+	}
+
+	return dst
 }

+ 8 - 2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/config_test.go

@@ -18,7 +18,7 @@ var copyTestConfig = Config{
 	HTTPClient:              http.DefaultClient,
 	LogLevel:                LogLevel(LogDebug),
 	Logger:                  NewDefaultLogger(),
-	MaxRetries:              Int(DefaultRetries),
+	MaxRetries:              Int(3),
 	DisableParamValidation:  Bool(true),
 	DisableComputeChecksums: Bool(true),
 	S3ForcePathStyle:        Bool(true),
@@ -31,6 +31,11 @@ func TestCopy(t *testing.T) {
 		t.Errorf("Copy() = %+v", got)
 		t.Errorf("    want %+v", want)
 	}
+
+	got.Region = String("other")
+	if got.Region == want.Region {
+		t.Errorf("Expect setting copy values not not reflect in source")
+	}
 }
 
 func TestCopyReturnsNewInstance(t *testing.T) {
@@ -69,7 +74,8 @@ var mergeTests = []struct {
 
 func TestMerge(t *testing.T) {
 	for i, tt := range mergeTests {
-		got := tt.cfg.Merge(tt.in)
+		got := tt.cfg.Copy()
+		got.MergeIn(tt.in)
 		if !reflect.DeepEqual(got, tt.want) {
 			t.Errorf("Config %d %+v", i, tt.cfg)
 			t.Errorf("   Merge(%+v)", tt.in)

+ 17 - 14
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go

@@ -8,6 +8,7 @@ import (
 	"net/http"
 	"net/url"
 	"regexp"
+	"runtime"
 	"strconv"
 
 	"github.com/aws/aws-sdk-go/aws"
@@ -23,7 +24,7 @@ type lener interface {
 // BuildContentLengthHandler builds the content length of a request based on the body,
 // or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
 // to determine request body length and no "Content-Length" was specified it will panic.
-var BuildContentLengthHandler = request.NamedHandler{"core.BuildContentLengthHandler", func(r *request.Request) {
+var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
 	if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
 		length, _ := strconv.ParseInt(slength, 10, 64)
 		r.HTTPRequest.ContentLength = length
@@ -49,17 +50,19 @@ var BuildContentLengthHandler = request.NamedHandler{"core.BuildContentLengthHan
 	r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
 }}
 
-// UserAgentHandler is a request handler for injecting User agent into requests.
-var UserAgentHandler = request.NamedHandler{"core.UserAgentHandler", func(r *request.Request) {
-	r.HTTPRequest.Header.Set("User-Agent", aws.SDKName+"/"+aws.SDKVersion)
-}}
+// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
+var SDKVersionUserAgentHandler = request.NamedHandler{
+	Name: "core.SDKVersionUserAgentHandler",
+	Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
+		runtime.Version(), runtime.GOOS, runtime.GOARCH),
+}
 
 var reStatusCode = regexp.MustCompile(`^(\d{3})`)
 
 // SendHandler is a request handler to send service request using HTTP client.
-var SendHandler = request.NamedHandler{"core.SendHandler", func(r *request.Request) {
+var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
 	var err error
-	r.HTTPResponse, err = r.Service.Config.HTTPClient.Do(r.HTTPRequest)
+	r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest)
 	if err != nil {
 		// Capture the case where url.Error is returned for error processing
 		// response. e.g. 301 without location header comes back as string
@@ -92,7 +95,7 @@ var SendHandler = request.NamedHandler{"core.SendHandler", func(r *request.Reque
 }}
 
 // ValidateResponseHandler is a request handler to validate service response.
-var ValidateResponseHandler = request.NamedHandler{"core.ValidateResponseHandler", func(r *request.Request) {
+var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
 	if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
 		// this may be replaced by an UnmarshalError handler
 		r.Error = awserr.New("UnknownError", "unknown error", nil)
@@ -101,7 +104,7 @@ var ValidateResponseHandler = request.NamedHandler{"core.ValidateResponseHandler
 
 // AfterRetryHandler performs final checks to determine if the request should
 // be retried and how long to delay.
-var AfterRetryHandler = request.NamedHandler{"core.AfterRetryHandler", func(r *request.Request) {
+var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
 	// If one of the other handlers already set the retry state
 	// we don't want to override it based on the service's state
 	if r.Retryable == nil {
@@ -110,13 +113,13 @@ var AfterRetryHandler = request.NamedHandler{"core.AfterRetryHandler", func(r *r
 
 	if r.WillRetry() {
 		r.RetryDelay = r.RetryRules(r)
-		r.Service.Config.SleepDelay(r.RetryDelay)
+		r.Config.SleepDelay(r.RetryDelay)
 
 		// when the expired token exception occurs the credentials
 		// need to be expired locally so that the next request to
 		// get credentials will trigger a credentials refresh.
 		if r.IsErrorExpired() {
-			r.Service.Config.Credentials.Expire()
+			r.Config.Credentials.Expire()
 		}
 
 		r.RetryCount++
@@ -127,10 +130,10 @@ var AfterRetryHandler = request.NamedHandler{"core.AfterRetryHandler", func(r *r
 // ValidateEndpointHandler is a request handler to validate a request had the
 // appropriate Region and Endpoint set. Will set r.Error if the endpoint or
 // region is not valid.
-var ValidateEndpointHandler = request.NamedHandler{"core.ValidateEndpointHandler", func(r *request.Request) {
-	if r.Service.SigningRegion == "" && aws.StringValue(r.Service.Config.Region) == "" {
+var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) {
+	if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
 		r.Error = aws.ErrMissingRegion
-	} else if r.Service.Endpoint == "" {
+	} else if r.ClientInfo.Endpoint == "" {
 		r.Error = aws.ErrMissingEndpoint
 	}
 }}

+ 11 - 5
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go

@@ -13,12 +13,13 @@ import (
 	"github.com/aws/aws-sdk-go/aws/corehandlers"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
+	"github.com/aws/aws-sdk-go/awstesting"
 )
 
 func TestValidateEndpointHandler(t *testing.T) {
 	os.Clearenv()
-	svc := service.New(aws.NewConfig().WithRegion("us-west-2"))
+
+	svc := awstesting.NewClient(aws.NewConfig().WithRegion("us-west-2"))
 	svc.Handlers.Clear()
 	svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
 
@@ -30,7 +31,8 @@ func TestValidateEndpointHandler(t *testing.T) {
 
 func TestValidateEndpointHandlerErrorRegion(t *testing.T) {
 	os.Clearenv()
-	svc := service.New(nil)
+
+	svc := awstesting.NewClient()
 	svc.Handlers.Clear()
 	svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
 
@@ -58,7 +60,11 @@ func (m *mockCredsProvider) IsExpired() bool {
 func TestAfterRetryRefreshCreds(t *testing.T) {
 	os.Clearenv()
 	credProvider := &mockCredsProvider{}
-	svc := service.New(&aws.Config{Credentials: credentials.NewCredentials(credProvider), MaxRetries: aws.Int(1)})
+
+	svc := awstesting.NewClient(&aws.Config{
+		Credentials: credentials.NewCredentials(credProvider),
+		MaxRetries:  aws.Int(1),
+	})
 
 	svc.Handlers.Clear()
 	svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) {
@@ -91,7 +97,7 @@ func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, e
 }
 
 func TestSendHandlerError(t *testing.T) {
-	svc := service.New(&aws.Config{
+	svc := awstesting.NewClient(&aws.Config{
 		HTTPClient: &http.Client{
 			Transport: &testSendHandlerTransport{},
 		},

+ 1 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go

@@ -12,7 +12,7 @@ import (
 
 // ValidateParametersHandler is a request handler to validate the input parameters.
 // Validating parameters only has meaning if done prior to the request being sent.
-var ValidateParametersHandler = request.NamedHandler{"core.ValidateParametersHandler", func(r *request.Request) {
+var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
 	if r.ParamsFilled() {
 		v := validator{errors: []string{}}
 		v.validateAny(reflect.ValueOf(r.Params), "")

+ 6 - 6
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go

@@ -7,17 +7,17 @@ import (
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/corehandlers"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
 	"github.com/stretchr/testify/require"
 )
 
-var testSvc = func() *service.Service {
-	s := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      &aws.Config{},
+var testSvc = func() *client.Client {
+	s := &client.Client{
+		Config: aws.Config{},
+		ClientInfo: metadata.ClientInfo{
 			ServiceName: "mock-service",
 			APIVersion:  "2015-01-01",
 		},

+ 34 - 29
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go

@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/ec2metadata"
 )
@@ -25,9 +26,6 @@ import (
 //         Client: &http.Client{
 //             Timeout: 10 * time.Second,
 //         },
-//         // Use default EC2 Role metadata endpoint, Alternate endpoints can be
-//         // specified setting Endpoint to something else.
-//         Endpoint: "",
 //         // Do not use early expiry of credentials. If a non zero value is
 //         // specified the credentials will be expired early
 //         ExpiryWindow: 0,
@@ -35,8 +33,8 @@ import (
 type EC2RoleProvider struct {
 	credentials.Expiry
 
-	// EC2Metadata client to use when connecting to EC2 metadata service
-	Client *ec2metadata.Client
+	// Required EC2Metadata client to use when connecting to EC2 metadata service.
+	Client *ec2metadata.EC2Metadata
 
 	// ExpiryWindow will allow the credentials to trigger refreshing prior to
 	// the credentials actually expiring. This is beneficial so race conditions
@@ -50,33 +48,40 @@ type EC2RoleProvider struct {
 	ExpiryWindow time.Duration
 }
 
-// NewCredentials returns a pointer to a new Credentials object
-// wrapping the EC2RoleProvider.
-//
-// Takes a custom http.Client which can be configured for custom handling of
-// things such as timeout.
-//
-// Endpoint is the URL that the EC2RoleProvider will connect to when retrieving
-// role and credentials.
-//
-// Window is the expiry window that will be subtracted from the expiry returned
-// by the role credential request. This is done so that the credentials will
-// expire sooner than their actual lifespan.
-func NewCredentials(client *ec2metadata.Client, window time.Duration) *credentials.Credentials {
-	return credentials.NewCredentials(&EC2RoleProvider{
-		Client:       client,
-		ExpiryWindow: window,
-	})
+// NewCredentials returns a pointer to a new Credentials object wrapping
+// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client.
+// The ConfigProvider is satisfied by the session.Session type.
+func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials {
+	p := &EC2RoleProvider{
+		Client: ec2metadata.New(c),
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping
+// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2
+// metadata service.
+func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials {
+	p := &EC2RoleProvider{
+		Client: client,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
 }
 
 // Retrieve retrieves credentials from the EC2 service.
 // Error will be returned if the request fails, or unable to extract
 // the desired credentials.
 func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
-	if m.Client == nil {
-		m.Client = ec2metadata.New(nil)
-	}
-
 	credsList, err := requestCredList(m.Client)
 	if err != nil {
 		return credentials.Value{}, err
@@ -101,7 +106,7 @@ func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
 	}, nil
 }
 
-// A ec2RoleCredRespBody provides the shape for deserializing credential
+// A ec2RoleCredRespBody provides the shape for unmarshalling credential
 // request responses.
 type ec2RoleCredRespBody struct {
 	// Success State
@@ -119,7 +124,7 @@ const iamSecurityCredsPath = "/iam/security-credentials"
 
 // requestCredList requests a list of credentials from the EC2 service.
 // If there are no credentials, or there is an error making or receiving the request
-func requestCredList(client *ec2metadata.Client) ([]string, error) {
+func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
 	resp, err := client.GetMetadata(iamSecurityCredsPath)
 	if err != nil {
 		return nil, awserr.New("EC2RoleRequestError", "failed to list EC2 Roles", err)
@@ -142,7 +147,7 @@ func requestCredList(client *ec2metadata.Client) ([]string, error) {
 //
 // If the credentials cannot be found, or there is an error reading the response
 // and error will be returned.
-func requestCred(client *ec2metadata.Client, credsName string) (ec2RoleCredRespBody, error) {
+func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
 	resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName))
 	if err != nil {
 		return ec2RoleCredRespBody{},

+ 14 - 16
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go

@@ -13,6 +13,7 @@ import (
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
 	"github.com/aws/aws-sdk-go/aws/ec2metadata"
+	"github.com/aws/aws-sdk-go/aws/session"
 )
 
 const credsRespTmpl = `{
@@ -54,11 +55,11 @@ func TestEC2RoleProvider(t *testing.T) {
 	defer server.Close()
 
 	p := &ec2rolecreds.EC2RoleProvider{
-		Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
+		Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
 	}
 
 	creds, err := p.Retrieve()
-	assert.Nil(t, err, "Expect no error")
+	assert.Nil(t, err, "Expect no error, %v", err)
 
 	assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
 	assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
@@ -70,7 +71,7 @@ func TestEC2RoleProviderFailAssume(t *testing.T) {
 	defer server.Close()
 
 	p := &ec2rolecreds.EC2RoleProvider{
-		Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
+		Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
 	}
 
 	creds, err := p.Retrieve()
@@ -91,7 +92,7 @@ func TestEC2RoleProviderIsExpired(t *testing.T) {
 	defer server.Close()
 
 	p := &ec2rolecreds.EC2RoleProvider{
-		Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
+		Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
 	}
 	p.CurrentTime = func() time.Time {
 		return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
@@ -100,7 +101,7 @@ func TestEC2RoleProviderIsExpired(t *testing.T) {
 	assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
 
 	_, err := p.Retrieve()
-	assert.Nil(t, err, "Expect no error")
+	assert.Nil(t, err, "Expect no error, %v", err)
 
 	assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
 
@@ -116,7 +117,7 @@ func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
 	defer server.Close()
 
 	p := &ec2rolecreds.EC2RoleProvider{
-		Client:       ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
+		Client:       ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
 		ExpiryWindow: time.Hour * 1,
 	}
 	p.CurrentTime = func() time.Time {
@@ -126,7 +127,7 @@ func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
 	assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
 
 	_, err := p.Retrieve()
-	assert.Nil(t, err, "Expect no error")
+	assert.Nil(t, err, "Expect no error, %v", err)
 
 	assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
 
@@ -137,12 +138,12 @@ func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
 	assert.True(t, p.IsExpired(), "Expect creds to be expired.")
 }
 
-func BenchmarkEC2RoleProvider(b *testing.B) {
+func BenchmarkEC3RoleProvider(b *testing.B) {
 	server := initTestServer("2014-12-16T01:51:37Z", false)
 	defer server.Close()
 
 	p := &ec2rolecreds.EC2RoleProvider{
-		Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
+		Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
 	}
 	_, err := p.Retrieve()
 	if err != nil {
@@ -150,12 +151,9 @@ func BenchmarkEC2RoleProvider(b *testing.B) {
 	}
 
 	b.ResetTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			_, err := p.Retrieve()
-			if err != nil {
-				b.Fatal(err)
-			}
+	for i := 0; i < b.N; i++ {
+		if _, err := p.Retrieve(); err != nil {
+			b.Fatal(err)
 		}
-	})
+	}
 }

+ 4 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/example.ini

@@ -6,3 +6,7 @@ aws_session_token = token
 [no_token]
 aws_access_key_id = accessKey
 aws_secret_access_key = secret
+
+[with_colon]
+aws_access_key_id: accessKey
+aws_secret_access_key: secret

+ 16 - 12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go

@@ -5,7 +5,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/vaughan0/go-ini"
+	"github.com/go-ini/ini"
 
 	"github.com/aws/aws-sdk-go/aws/awserr"
 )
@@ -76,32 +76,36 @@ func (p *SharedCredentialsProvider) IsExpired() bool {
 // The credentials retrieved from the profile will be returned or error. Error will be
 // returned if it fails to read from the file, or the data is invalid.
 func loadProfile(filename, profile string) (Value, error) {
-	config, err := ini.LoadFile(filename)
+	config, err := ini.Load(filename)
 	if err != nil {
 		return Value{}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
 	}
-	iniProfile := config.Section(profile)
+	iniProfile, err := config.GetSection(profile)
+	if err != nil {
+		return Value{}, awserr.New("SharedCredsLoad", "failed to get profile", err)
+	}
 
-	id, ok := iniProfile["aws_access_key_id"]
-	if !ok {
+	id, err := iniProfile.GetKey("aws_access_key_id")
+	if err != nil {
 		return Value{}, awserr.New("SharedCredsAccessKey",
 			fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
-			nil)
+			err)
 	}
 
-	secret, ok := iniProfile["aws_secret_access_key"]
-	if !ok {
+	secret, err := iniProfile.GetKey("aws_secret_access_key")
+	if err != nil {
 		return Value{}, awserr.New("SharedCredsSecret",
 			fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
 			nil)
 	}
 
-	token := iniProfile["aws_session_token"]
+	// Default to empty string if not found
+	token := iniProfile.Key("aws_session_token")
 
 	return Value{
-		AccessKeyID:     id,
-		SecretAccessKey: secret,
-		SessionToken:    token,
+		AccessKeyID:     id.String(),
+		SecretAccessKey: secret.String(),
+		SessionToken:    token.String(),
 	}, nil
 }
 

+ 12 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go

@@ -69,6 +69,18 @@ func TestSharedCredentialsProviderWithoutTokenFromProfile(t *testing.T) {
 	assert.Empty(t, creds.SessionToken, "Expect no token")
 }
 
+func TestSharedCredentialsProviderColonInCredFile(t *testing.T) {
+	os.Clearenv()
+
+	p := SharedCredentialsProvider{Filename: "example.ini", Profile: "with_colon"}
+	creds, err := p.Retrieve()
+	assert.Nil(t, err, "Expect no error")
+
+	assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
+	assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
+	assert.Empty(t, creds.SessionToken, "Expect no token")
+}
+
 func BenchmarkSharedCredentialsProvider(b *testing.B) {
 	os.Clearenv()
 

+ 40 - 35
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go

@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/service/sts"
 )
@@ -18,31 +19,17 @@ type AssumeRoler interface {
 	AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
 }
 
+// DefaultDuration is the default amount of time in minutes that the credentials
+// will be valid for.
+var DefaultDuration = time.Duration(15) * time.Minute
+
 // AssumeRoleProvider retrieves temporary credentials from the STS service, and
 // keeps track of their expiration time. This provider must be used explicitly,
 // as it is not included in the credentials chain.
-//
-// Example how to configure a service to use this provider:
-//
-//		config := &aws.Config{
-//			Credentials: stscreds.NewCredentials(nil, "arn-of-the-role-to-assume", 10*time.Second),
-//		})
-//		// Use config for creating your AWS service.
-//
-// Example how to obtain customised credentials:
-//
-//		provider := &stscreds.Provider{
-//			// Extend the duration to 1 hour.
-//			Duration: time.Hour,
-//			// Custom role name.
-//			RoleSessionName: "custom-session-name",
-//		}
-//		creds := credentials.NewCredentials(provider)
-//
 type AssumeRoleProvider struct {
 	credentials.Expiry
 
-	// Custom STS client. If not set the default STS client will be used.
+	// STS client to make assume role request with.
 	Client AssumeRoler
 
 	// Role to be assumed.
@@ -70,37 +57,55 @@ type AssumeRoleProvider struct {
 }
 
 // NewCredentials returns a pointer to a new Credentials object wrapping the
-// AssumeRoleProvider.  The credentials will expire every 15 minutes and the
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the
 // role will be named after a nanosecond timestamp of this operation.
 //
-// The sts and roleARN parameters are used for building the "AssumeRole" call.
-// Pass nil as sts to use the default client.
+// Takes a Config provider to create the STS client. The ConfigProvider is
+// satisfied by the session.Session type.
+func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
+	p := &AssumeRoleProvider{
+		Client:   sts.New(c),
+		RoleARN:  roleARN,
+		Duration: DefaultDuration,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the
+// role will be named after a nanosecond timestamp of this operation.
 //
-// Window is the expiry window that will be subtracted from the expiry returned
-// by the role credential request. This is done so that the credentials will
-// expire sooner than their actual lifespan.
-func NewCredentials(client AssumeRoler, roleARN string, window time.Duration) *credentials.Credentials {
-	return credentials.NewCredentials(&AssumeRoleProvider{
-		Client:       client,
-		RoleARN:      roleARN,
-		ExpiryWindow: window,
-	})
+// Takes an AssumeRoler which can be satisfiede by the STS client.
+func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
+	p := &AssumeRoleProvider{
+		Client:   svc,
+		RoleARN:  roleARN,
+		Duration: DefaultDuration,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
 }
 
 // Retrieve generates a new set of temporary credentials using STS.
 func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
 
 	// Apply defaults where parameters are not set.
-	if p.Client == nil {
-		p.Client = sts.New(nil)
-	}
 	if p.RoleSessionName == "" {
 		// Try to work out a role name that will hopefully end up unique.
 		p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
 	}
 	if p.Duration == 0 {
 		// Expire as often as AWS permits.
-		p.Duration = 15 * time.Minute
+		p.Duration = DefaultDuration
 	}
 
 	roleOutput, err := p.Client.AssumeRole(&sts.AssumeRoleInput{

+ 4 - 7
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go

@@ -48,12 +48,9 @@ func BenchmarkAssumeRoleProvider(b *testing.B) {
 	}
 
 	b.ResetTimer()
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			_, err := p.Retrieve()
-			if err != nil {
-				b.Fatal(err)
-			}
+	for i := 0; i < b.N; i++ {
+		if _, err := p.Retrieve(); err != nil {
+			b.Fatal(err)
 		}
-	})
+	}
 }

+ 64 - 27
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/defaults/defaults.go

@@ -1,3 +1,5 @@
+// Package defaults is a collection of helpers to retrieve the SDK's default
+// configuration and handlers.
 package defaults
 
 import (
@@ -6,34 +8,69 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/corehandlers"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
+	"github.com/aws/aws-sdk-go/aws/ec2metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/endpoints"
 )
 
-// DefaultChainCredentials is a Credentials which will find the first available
-// credentials Value from the list of Providers.
-//
-// This should be used in the default case. Once the type of credentials are
-// known switching to the specific Credentials will be more efficient.
-var DefaultChainCredentials = credentials.NewChainCredentials(
-	[]credentials.Provider{
-		&credentials.EnvProvider{},
-		&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
-		&ec2rolecreds.EC2RoleProvider{ExpiryWindow: 5 * time.Minute},
-	})
-
-// DefaultConfig is the default all service configuration will be based off of.
-// By default, all clients use this structure for initialization options unless
-// a custom configuration object is passed in.
-//
-// You may modify this global structure to change all default configuration
-// in the SDK. Note that configuration options are copied by value, so any
-// modifications must happen before constructing a client.
-var DefaultConfig = aws.NewConfig().
-	WithCredentials(DefaultChainCredentials).
-	WithRegion(os.Getenv("AWS_REGION")).
-	WithHTTPClient(http.DefaultClient).
-	WithMaxRetries(aws.DefaultRetries).
-	WithLogger(aws.NewDefaultLogger()).
-	WithLogLevel(aws.LogOff).
-	WithSleepDelay(time.Sleep)
+// A Defaults provides a collection of default values for SDK clients.
+type Defaults struct {
+	Config   *aws.Config
+	Handlers request.Handlers
+}
+
+// Get returns the SDK's default values with Config and handlers pre-configured.
+func Get() Defaults {
+	cfg := Config()
+	handlers := Handlers()
+	cfg.Credentials = CredChain(cfg, handlers)
+
+	return Defaults{
+		Config:   cfg,
+		Handlers: handlers,
+	}
+}
+
+// Config returns the default configuration.
+func Config() *aws.Config {
+	return aws.NewConfig().
+		WithCredentials(credentials.AnonymousCredentials).
+		WithRegion(os.Getenv("AWS_REGION")).
+		WithHTTPClient(http.DefaultClient).
+		WithMaxRetries(aws.UseServiceDefaultRetries).
+		WithLogger(aws.NewDefaultLogger()).
+		WithLogLevel(aws.LogOff).
+		WithSleepDelay(time.Sleep)
+}
+
+// Handlers returns the default request handlers.
+func Handlers() request.Handlers {
+	var handlers request.Handlers
+
+	handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
+	handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
+	handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
+	handlers.Send.PushBackNamed(corehandlers.SendHandler)
+	handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
+	handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
+
+	return handlers
+}
+
+// CredChain returns the default credential chain.
+func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
+	endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
+
+	return credentials.NewChainCredentials(
+		[]credentials.Provider{
+			&credentials.EnvProvider{},
+			&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
+			&ec2rolecreds.EC2RoleProvider{
+				Client:       ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
+				ExpiryWindow: 5 * time.Minute,
+			},
+		})
+}

+ 4 - 4
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go

@@ -7,7 +7,7 @@ import (
 )
 
 // GetMetadata uses the path provided to request
-func (c *Client) GetMetadata(p string) (string, error) {
+func (c *EC2Metadata) GetMetadata(p string) (string, error) {
 	op := &request.Operation{
 		Name:       "GetMetadata",
 		HTTPMethod: "GET",
@@ -15,13 +15,13 @@ func (c *Client) GetMetadata(p string) (string, error) {
 	}
 
 	output := &metadataOutput{}
-	req := request.New(c.Service.ServiceInfo, c.Service.Handlers, c.Service.Retryer, op, nil, output)
+	req := c.NewRequest(op, nil, output)
 
 	return output.Content, req.Send()
 }
 
 // Region returns the region the instance is running in.
-func (c *Client) Region() (string, error) {
+func (c *EC2Metadata) Region() (string, error) {
 	resp, err := c.GetMetadata("placement/availability-zone")
 	if err != nil {
 		return "", err
@@ -34,7 +34,7 @@ func (c *Client) Region() (string, error) {
 // Available returns if the application has access to the EC2 Metadata service.
 // Can be used to determine if application is running within an EC2 Instance and
 // the metadata service is available.
-func (c *Client) Available() bool {
+func (c *EC2Metadata) Available() bool {
 	if _, err := c.GetMetadata("instance-id"); err != nil {
 		return false
 	}

+ 8 - 7
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go

@@ -14,6 +14,7 @@ import (
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/ec2metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/aws/session"
 )
 
 func initTestServer(path string, resp string) *httptest.Server {
@@ -28,15 +29,15 @@ func initTestServer(path string, resp string) *httptest.Server {
 }
 
 func TestEndpoint(t *testing.T) {
-	c := ec2metadata.New(&ec2metadata.Config{})
+	c := ec2metadata.New(session.New())
 	op := &request.Operation{
 		Name:       "GetMetadata",
 		HTTPMethod: "GET",
 		HTTPPath:   path.Join("/", "meta-data", "testpath"),
 	}
 
-	req := c.Service.NewRequest(op, nil, nil)
-	assert.Equal(t, "http://169.254.169.254/latest", req.Service.Endpoint)
+	req := c.NewRequest(op, nil, nil)
+	assert.Equal(t, "http://169.254.169.254/latest", req.ClientInfo.Endpoint)
 	assert.Equal(t, "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String())
 }
 
@@ -46,7 +47,7 @@ func TestGetMetadata(t *testing.T) {
 		"success", // real response includes suffix
 	)
 	defer server.Close()
-	c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")})
+	c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
 
 	resp, err := c.GetMetadata("some/path")
 
@@ -60,7 +61,7 @@ func TestGetRegion(t *testing.T) {
 		"us-west-2a", // real response includes suffix
 	)
 	defer server.Close()
-	c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")})
+	c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
 
 	region, err := c.Region()
 
@@ -74,7 +75,7 @@ func TestMetadataAvailable(t *testing.T) {
 		"instance-id",
 	)
 	defer server.Close()
-	c := ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")})
+	c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
 
 	available := c.Available()
 
@@ -82,7 +83,7 @@ func TestMetadataAvailable(t *testing.T) {
 }
 
 func TestMetadataNotAvailable(t *testing.T) {
-	c := ec2metadata.New(nil)
+	c := ec2metadata.New(session.New())
 	c.Handlers.Send.Clear()
 	c.Handlers.Send.PushBack(func(r *request.Request) {
 		r.HTTPResponse = &http.Response{

+ 49 - 82
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go

@@ -1,3 +1,5 @@
+// Package ec2metadata provides the client for making API calls to the
+// EC2 Metadata service.
 package ec2metadata
 
 import (
@@ -8,89 +10,41 @@ import (
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
 )
 
-// DefaultRetries states the default number of times the service client will
-// attempt to retry a failed request before failing.
-const DefaultRetries = 3
-
-// A Config provides the configuration for the EC2 Metadata service.
-type Config struct {
-	// An optional endpoint URL (hostname only or fully qualified URI)
-	// that overrides the default service endpoint for a client. Set this
-	// to nil, or `""` to use the default service endpoint.
-	Endpoint *string
-
-	// The HTTP client to use when sending requests. Defaults to
-	// `http.DefaultClient`.
-	HTTPClient *http.Client
-
-	// An integer value representing the logging level. The default log level
-	// is zero (LogOff), which represents no logging. To enable logging set
-	// to a LogLevel Value.
-	Logger aws.Logger
-
-	// The logger writer interface to write logging messages to. Defaults to
-	// standard out.
-	LogLevel *aws.LogLevelType
-
-	// The maximum number of times that a request will be retried for failures.
-	// Defaults to DefaultRetries for the number of retries to be performed
-	// per request.
-	MaxRetries *int
-}
+// ServiceName is the name of the service.
+const ServiceName = "ec2metadata"
 
-// A Client is an EC2 Metadata service Client.
-type Client struct {
-	*service.Service
+// A EC2Metadata is an EC2 Metadata service Client.
+type EC2Metadata struct {
+	*client.Client
 }
 
-// New creates a new instance of the EC2 Metadata service client.
+// New creates a new instance of the EC2Metadata client with a session.
+// This client is safe to use across multiple goroutines.
 //
-// In the general use case the configuration for this service client should not
-// be needed and `nil` can be provided. Configuration is only needed if the
-// `ec2metadata.Config` defaults need to be overridden. Eg. Setting LogLevel.
+// Example:
+//     // Create a EC2Metadata client from just a session.
+//     svc := ec2metadata.New(mySession)
 //
-// @note This configuration will NOT be merged with the default AWS service
-// client configuration `defaults.DefaultConfig`. Due to circular dependencies
-// with the defaults package and credentials EC2 Role Provider.
-func New(config *Config) *Client {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      copyConfig(config),
-			ServiceName: "Client",
-			Endpoint:    "http://169.254.169.254/latest",
-			APIVersion:  "latest",
-		},
-	}
-	service.Initialize()
-	service.Handlers.Unmarshal.PushBack(unmarshalHandler)
-	service.Handlers.UnmarshalError.PushBack(unmarshalError)
-	service.Handlers.Validate.Clear()
-	service.Handlers.Validate.PushBack(validateEndpointHandler)
-
-	return &Client{service}
+//     // Create a EC2Metadata client with additional configuration
+//     svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
+	c := p.ClientConfig(ServiceName, cfgs...)
+	return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
 }
 
-func copyConfig(config *Config) *aws.Config {
-	if config == nil {
-		config = &Config{}
-	}
-	c := &aws.Config{
-		Credentials: credentials.AnonymousCredentials,
-		Endpoint:    config.Endpoint,
-		HTTPClient:  config.HTTPClient,
-		Logger:      config.Logger,
-		LogLevel:    config.LogLevel,
-		MaxRetries:  config.MaxRetries,
-	}
-
-	if c.HTTPClient == nil {
-		c.HTTPClient = &http.Client{
+// NewClient returns a new EC2Metadata client. Should be used to create
+// a client when not using a session. Generally using just New with a session
+// is preferred.
+func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
+	// If the default http client is provided, replace it with a custom
+	// client using default timeouts.
+	if cfg.HTTPClient == http.DefaultClient {
+		cfg.HTTPClient = &http.Client{
 			Transport: &http.Transport{
 				Proxy: http.ProxyFromEnvironment,
 				Dial: (&net.Dialer{
@@ -104,17 +58,30 @@ func copyConfig(config *Config) *aws.Config {
 			},
 		}
 	}
-	if c.Logger == nil {
-		c.Logger = aws.NewDefaultLogger()
-	}
-	if c.LogLevel == nil {
-		c.LogLevel = aws.LogLevel(aws.LogOff)
+
+	svc := &EC2Metadata{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName: ServiceName,
+				Endpoint:    endpoint,
+				APIVersion:  "latest",
+			},
+			handlers,
+		),
 	}
-	if c.MaxRetries == nil {
-		c.MaxRetries = aws.Int(DefaultRetries)
+
+	svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
+	svc.Handlers.UnmarshalError.PushBack(unmarshalError)
+	svc.Handlers.Validate.Clear()
+	svc.Handlers.Validate.PushBack(validateEndpointHandler)
+
+	// Add additional options to the service config
+	for _, option := range opts {
+		option(svc.Client)
 	}
 
-	return c
+	return svc
 }
 
 type metadataOutput struct {
@@ -143,7 +110,7 @@ func unmarshalError(r *request.Request) {
 }
 
 func validateEndpointHandler(r *request.Request) {
-	if r.Service.Endpoint == "" {
+	if r.ClientInfo.Endpoint == "" {
 		r.Error = aws.ErrMissingEndpoint
 	}
 }

+ 2 - 2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/errors.go

@@ -7,11 +7,11 @@ var (
 	// not found.
 	//
 	// @readonly
-	ErrMissingRegion error = awserr.New("MissingRegion", "could not find region configuration", nil)
+	ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
 
 	// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
 	// resolved for a service.
 	//
 	// @readonly
-	ErrMissingEndpoint error = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
+	ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
 )

+ 28 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers.go

@@ -1,5 +1,10 @@
 package request
 
+import (
+	"fmt"
+	"strings"
+)
+
 // A Handlers provides a collection of request handlers for various
 // stages of handling requests.
 type Handlers struct {
@@ -110,3 +115,26 @@ func (l *HandlerList) Run(r *Request) {
 		f.Fn(r)
 	}
 }
+
+// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
+// header. If the extra parameters are provided they will be added as metadata to the
+// name/version pair resulting in the following format.
+// "name/version (extra0; extra1; ...)"
+// The user agent part will be concatenated with this current request's user agent string.
+func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) {
+	ua := fmt.Sprintf("%s/%s", name, version)
+	if len(extra) > 0 {
+		ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; "))
+	}
+	return func(r *Request) {
+		AddToUserAgent(r, ua)
+	}
+}
+
+// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header.
+// The input string will be concatenated with the current request's user agent string.
+func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
+	return func(r *Request) {
+		AddToUserAgent(r, s)
+	}
+}

+ 2 - 2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/handlers_test.go

@@ -35,8 +35,8 @@ func TestMultipleHandlers(t *testing.T) {
 
 func TestNamedHandlers(t *testing.T) {
 	l := request.HandlerList{}
-	named := request.NamedHandler{"Name", func(r *request.Request) {}}
-	named2 := request.NamedHandler{"NotName", func(r *request.Request) {}}
+	named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {}}
+	named2 := request.NamedHandler{Name: "NotName", Fn: func(r *request.Request) {}}
 	l.PushBackNamed(named)
 	l.PushBackNamed(named)
 	l.PushBackNamed(named2)

+ 26 - 95
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request.go

@@ -12,15 +12,16 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awsutil"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 )
 
 // A Request is the service request to be made.
 type Request struct {
+	Config     aws.Config
+	ClientInfo metadata.ClientInfo
+	Handlers   Handlers
+
 	Retryer
-	Service      serviceinfo.ServiceInfo
-	Handlers     Handlers
 	Time         time.Time
 	ExpireTime   time.Duration
 	Operation    *Operation
@@ -32,7 +33,7 @@ type Request struct {
 	Error        error
 	Data         interface{}
 	RequestID    string
-	RetryCount   uint
+	RetryCount   int
 	Retryable    *bool
 	RetryDelay   time.Duration
 
@@ -61,7 +62,9 @@ type Paginator struct {
 // Params is any value of input parameters to be the request payload.
 // Data is pointer value to an object which the request's response
 // payload will be deserialized to.
-func New(service serviceinfo.ServiceInfo, handlers Handlers, retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
+func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
+	retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
+
 	method := operation.HTTPMethod
 	if method == "" {
 		method = "POST"
@@ -72,12 +75,14 @@ func New(service serviceinfo.ServiceInfo, handlers Handlers, retryer Retryer, op
 	}
 
 	httpReq, _ := http.NewRequest(method, "", nil)
-	httpReq.URL, _ = url.Parse(service.Endpoint + p)
+	httpReq.URL, _ = url.Parse(clientInfo.Endpoint + p)
 
 	r := &Request{
+		Config:     cfg,
+		ClientInfo: clientInfo,
+		Handlers:   handlers.Copy(),
+
 		Retryer:     retryer,
-		Service:     service,
-		Handlers:    handlers.Copy(),
 		Time:        time.Now(),
 		ExpireTime:  0,
 		Operation:   operation,
@@ -140,7 +145,7 @@ func (r *Request) Presign(expireTime time.Duration) (string, error) {
 }
 
 func debugLogReqError(r *Request, stage string, retrying bool, err error) {
-	if !r.Service.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
+	if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
 		return
 	}
 
@@ -149,8 +154,8 @@ func debugLogReqError(r *Request, stage string, retrying bool, err error) {
 		retryStr = "will retry"
 	}
 
-	r.Service.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
-		stage, r.Service.ServiceName, r.Operation.Name, retryStr, err))
+	r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
+		stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
 }
 
 // Build will build the request's object so it can be signed and sent
@@ -205,9 +210,9 @@ func (r *Request) Send() error {
 		}
 
 		if aws.BoolValue(r.Retryable) {
-			if r.Service.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
-				r.Service.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
-					r.Service.ServiceName, r.Operation.Name, r.RetryCount))
+			if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
+				r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
+					r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
 			}
 
 			// Re-seek the body back to the original point in for a retry so that
@@ -264,85 +269,11 @@ func (r *Request) Send() error {
 	return nil
 }
 
-// HasNextPage returns true if this request has more pages of data available.
-func (r *Request) HasNextPage() bool {
-	return r.nextPageTokens() != nil
-}
-
-// nextPageTokens returns the tokens to use when asking for the next page of
-// data.
-func (r *Request) nextPageTokens() []interface{} {
-	if r.Operation.Paginator == nil {
-		return nil
-	}
-
-	if r.Operation.TruncationToken != "" {
-		tr := awsutil.ValuesAtAnyPath(r.Data, r.Operation.TruncationToken)
-		if tr == nil || len(tr) == 0 {
-			return nil
-		}
-		switch v := tr[0].(type) {
-		case bool:
-			if v == false {
-				return nil
-			}
-		}
-	}
-
-	found := false
-	tokens := make([]interface{}, len(r.Operation.OutputTokens))
-
-	for i, outtok := range r.Operation.OutputTokens {
-		v := awsutil.ValuesAtAnyPath(r.Data, outtok)
-		if v != nil && len(v) > 0 {
-			found = true
-			tokens[i] = v[0]
-		}
-	}
-
-	if found {
-		return tokens
-	}
-	return nil
-}
-
-// NextPage returns a new Request that can be executed to return the next
-// page of result data. Call .Send() on this request to execute it.
-func (r *Request) NextPage() *Request {
-	tokens := r.nextPageTokens()
-	if tokens == nil {
-		return nil
-	}
-
-	data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
-	nr := New(r.Service, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
-	for i, intok := range nr.Operation.InputTokens {
-		awsutil.SetValueAtAnyPath(nr.Params, intok, tokens[i])
+// AddToUserAgent adds the string to the end of the request's current user agent.
+func AddToUserAgent(r *Request, s string) {
+	curUA := r.HTTPRequest.Header.Get("User-Agent")
+	if len(curUA) > 0 {
+		s = curUA + " " + s
 	}
-	return nr
-}
-
-// EachPage iterates over each page of a paginated request object. The fn
-// parameter should be a function with the following sample signature:
-//
-//   func(page *T, lastPage bool) bool {
-//       return true // return false to stop iterating
-//   }
-//
-// Where "T" is the structure type matching the output structure of the given
-// operation. For example, a request object generated by
-// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
-// as the structure "T". The lastPage value represents whether the page is
-// the last page of data or not. The return value of this function should
-// return true to keep iterating or false to stop.
-func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
-	for page := r; page != nil; page = page.NextPage() {
-		page.Send()
-		shouldContinue := fn(page.Data, !page.HasNextPage())
-		if page.Error != nil || !shouldContinue {
-			return page.Error
-		}
-	}
-
-	return nil
+	r.HTTPRequest.Header.Set("User-Agent", s)
 }

+ 104 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination.go

@@ -0,0 +1,104 @@
+package request
+
+import (
+	"reflect"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+)
+
+//type Paginater interface {
+//	HasNextPage() bool
+//	NextPage() *Request
+//	EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error
+//}
+
+// HasNextPage returns true if this request has more pages of data available.
+func (r *Request) HasNextPage() bool {
+	return len(r.nextPageTokens()) > 0
+}
+
+// nextPageTokens returns the tokens to use when asking for the next page of
+// data.
+func (r *Request) nextPageTokens() []interface{} {
+	if r.Operation.Paginator == nil {
+		return nil
+	}
+
+	if r.Operation.TruncationToken != "" {
+		tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
+		if len(tr) == 0 {
+			return nil
+		}
+
+		switch v := tr[0].(type) {
+		case *bool:
+			if !aws.BoolValue(v) {
+				return nil
+			}
+		case bool:
+			if v == false {
+				return nil
+			}
+		}
+	}
+
+	tokens := []interface{}{}
+	tokenAdded := false
+	for _, outToken := range r.Operation.OutputTokens {
+		v, _ := awsutil.ValuesAtPath(r.Data, outToken)
+		if len(v) > 0 {
+			tokens = append(tokens, v[0])
+			tokenAdded = true
+		} else {
+			tokens = append(tokens, nil)
+		}
+	}
+	if !tokenAdded {
+		return nil
+	}
+
+	return tokens
+}
+
+// NextPage returns a new Request that can be executed to return the next
+// page of result data. Call .Send() on this request to execute it.
+func (r *Request) NextPage() *Request {
+	tokens := r.nextPageTokens()
+	if len(tokens) == 0 {
+		return nil
+	}
+
+	data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
+	nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
+	for i, intok := range nr.Operation.InputTokens {
+		awsutil.SetValueAtPath(nr.Params, intok, tokens[i])
+	}
+	return nr
+}
+
+// EachPage iterates over each page of a paginated request object. The fn
+// parameter should be a function with the following sample signature:
+//
+//   func(page *T, lastPage bool) bool {
+//       return true // return false to stop iterating
+//   }
+//
+// Where "T" is the structure type matching the output structure of the given
+// operation. For example, a request object generated by
+// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
+// as the structure "T". The lastPage value represents whether the page is
+// the last page of data or not. The return value of this function should
+// return true to keep iterating or false to stop.
+func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
+	for page := r; page != nil; page = page.NextPage() {
+		if err := page.Send(); err != nil {
+			return err
+		}
+		if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage {
+			return page.Error
+		}
+	}
+
+	return nil
+}

+ 160 - 12
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go

@@ -9,14 +9,101 @@ import (
 	"github.com/aws/aws-sdk-go/aws/request"
 	"github.com/aws/aws-sdk-go/awstesting/unit"
 	"github.com/aws/aws-sdk-go/service/dynamodb"
+	"github.com/aws/aws-sdk-go/service/route53"
 	"github.com/aws/aws-sdk-go/service/s3"
 )
 
-var _ = unit.Imported
+// Use DynamoDB methods for simplicity
+func TestPaginationQueryPage(t *testing.T) {
+	db := dynamodb.New(unit.Session)
+	tokens, pages, numPages, gotToEnd := []map[string]*dynamodb.AttributeValue{}, []map[string]*dynamodb.AttributeValue{}, 0, false
+
+	reqNum := 0
+	resps := []*dynamodb.QueryOutput{
+		{
+			LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
+			Count:            aws.Int64(1),
+			Items: []map[string]*dynamodb.AttributeValue{
+				map[string]*dynamodb.AttributeValue{
+					"key": {S: aws.String("key1")},
+				},
+			},
+		},
+		{
+			LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
+			Count:            aws.Int64(1),
+			Items: []map[string]*dynamodb.AttributeValue{
+				map[string]*dynamodb.AttributeValue{
+					"key": {S: aws.String("key2")},
+				},
+			},
+		},
+		{
+			LastEvaluatedKey: map[string]*dynamodb.AttributeValue{},
+			Count:            aws.Int64(1),
+			Items: []map[string]*dynamodb.AttributeValue{
+				map[string]*dynamodb.AttributeValue{
+					"key": {S: aws.String("key3")},
+				},
+			},
+		},
+	}
+
+	db.Handlers.Send.Clear() // mock sending
+	db.Handlers.Unmarshal.Clear()
+	db.Handlers.UnmarshalMeta.Clear()
+	db.Handlers.ValidateResponse.Clear()
+	db.Handlers.Build.PushBack(func(r *request.Request) {
+		in := r.Params.(*dynamodb.QueryInput)
+		if in == nil {
+			tokens = append(tokens, nil)
+		} else if len(in.ExclusiveStartKey) != 0 {
+			tokens = append(tokens, in.ExclusiveStartKey)
+		}
+	})
+	db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	params := &dynamodb.QueryInput{
+		Limit:     aws.Int64(2),
+		TableName: aws.String("tablename"),
+	}
+	err := db.QueryPages(params, func(p *dynamodb.QueryOutput, last bool) bool {
+		numPages++
+		for _, item := range p.Items {
+			pages = append(pages, item)
+		}
+		if last {
+			if gotToEnd {
+				assert.Fail(t, "last=true happened twice")
+			}
+			gotToEnd = true
+		}
+		return true
+	})
+	assert.Nil(t, err)
+
+	assert.Equal(t,
+		[]map[string]*dynamodb.AttributeValue{
+			map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
+			map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
+		}, tokens)
+	assert.Equal(t,
+		[]map[string]*dynamodb.AttributeValue{
+			map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
+			map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
+			map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key3")}},
+		}, pages)
+	assert.Equal(t, 3, numPages)
+	assert.True(t, gotToEnd)
+	assert.Nil(t, params.ExclusiveStartKey)
+}
 
 // Use DynamoDB methods for simplicity
 func TestPagination(t *testing.T) {
-	db := dynamodb.New(nil)
+	db := dynamodb.New(unit.Session)
 	tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
 
 	reqNum := 0
@@ -68,7 +155,7 @@ func TestPagination(t *testing.T) {
 
 // Use DynamoDB methods for simplicity
 func TestPaginationEachPage(t *testing.T) {
-	db := dynamodb.New(nil)
+	db := dynamodb.New(unit.Session)
 	tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
 
 	reqNum := 0
@@ -121,7 +208,7 @@ func TestPaginationEachPage(t *testing.T) {
 
 // Use DynamoDB methods for simplicity
 func TestPaginationEarlyExit(t *testing.T) {
-	db := dynamodb.New(nil)
+	db := dynamodb.New(unit.Session)
 	numPages, gotToEnd := 0, false
 
 	reqNum := 0
@@ -161,7 +248,7 @@ func TestPaginationEarlyExit(t *testing.T) {
 }
 
 func TestSkipPagination(t *testing.T) {
-	client := s3.New(nil)
+	client := s3.New(unit.Session)
 	client.Handlers.Send.Clear() // mock sending
 	client.Handlers.Unmarshal.Clear()
 	client.Handlers.UnmarshalMeta.Clear()
@@ -186,10 +273,9 @@ func TestSkipPagination(t *testing.T) {
 
 // Use S3 for simplicity
 func TestPaginationTruncation(t *testing.T) {
-	count := 0
-	client := s3.New(nil)
+	client := s3.New(unit.Session)
 
-	reqNum := &count
+	reqNum := 0
 	resps := []*s3.ListObjectsOutput{
 		{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key1")}}},
 		{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key2")}}},
@@ -202,8 +288,8 @@ func TestPaginationTruncation(t *testing.T) {
 	client.Handlers.UnmarshalMeta.Clear()
 	client.Handlers.ValidateResponse.Clear()
 	client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
-		r.Data = resps[*reqNum]
-		*reqNum++
+		r.Data = resps[reqNum]
+		reqNum++
 	})
 
 	params := &s3.ListObjectsInput{Bucket: aws.String("bucket")}
@@ -218,7 +304,7 @@ func TestPaginationTruncation(t *testing.T) {
 	assert.Nil(t, err)
 
 	// Try again without truncation token at all
-	count = 0
+	reqNum = 0
 	resps[1].IsTruncated = nil
 	resps[2].IsTruncated = aws.Bool(true)
 	results = []string{}
@@ -229,7 +315,69 @@ func TestPaginationTruncation(t *testing.T) {
 
 	assert.Equal(t, []string{"Key1", "Key2"}, results)
 	assert.Nil(t, err)
+}
+
+func TestPaginationNilToken(t *testing.T) {
+	client := route53.New(unit.Session)
+
+	reqNum := 0
+	resps := []*route53.ListResourceRecordSetsOutput{
+		{
+			ResourceRecordSets: []*route53.ResourceRecordSet{
+				{Name: aws.String("first.example.com.")},
+			},
+			IsTruncated:          aws.Bool(true),
+			NextRecordName:       aws.String("second.example.com."),
+			NextRecordType:       aws.String("MX"),
+			NextRecordIdentifier: aws.String("second"),
+			MaxItems:             aws.String("1"),
+		},
+		{
+			ResourceRecordSets: []*route53.ResourceRecordSet{
+				{Name: aws.String("second.example.com.")},
+			},
+			IsTruncated:    aws.Bool(true),
+			NextRecordName: aws.String("third.example.com."),
+			NextRecordType: aws.String("MX"),
+			MaxItems:       aws.String("1"),
+		},
+		{
+			ResourceRecordSets: []*route53.ResourceRecordSet{
+				{Name: aws.String("third.example.com.")},
+			},
+			IsTruncated: aws.Bool(false),
+			MaxItems:    aws.String("1"),
+		},
+	}
+	client.Handlers.Send.Clear() // mock sending
+	client.Handlers.Unmarshal.Clear()
+	client.Handlers.UnmarshalMeta.Clear()
+	client.Handlers.ValidateResponse.Clear()
+
+	idents := []string{}
+	client.Handlers.Build.PushBack(func(r *request.Request) {
+		p := r.Params.(*route53.ListResourceRecordSetsInput)
+		idents = append(idents, aws.StringValue(p.StartRecordIdentifier))
+
+	})
+	client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	params := &route53.ListResourceRecordSetsInput{
+		HostedZoneId: aws.String("id-zone"),
+	}
+
+	results := []string{}
+	err := client.ListResourceRecordSetsPages(params, func(p *route53.ListResourceRecordSetsOutput, last bool) bool {
+		results = append(results, *p.ResourceRecordSets[0].Name)
+		return true
+	})
 
+	assert.NoError(t, err)
+	assert.Equal(t, []string{"", "second", ""}, idents)
+	assert.Equal(t, []string{"first.example.com.", "second.example.com.", "third.example.com."}, results)
 }
 
 // Benchmarks
@@ -251,7 +399,7 @@ var benchResps = []*dynamodb.ListTablesOutput{
 }
 
 var benchDb = func() *dynamodb.DynamoDB {
-	db := dynamodb.New(nil)
+	db := dynamodb.New(unit.Session)
 	db.Handlers.Send.Clear() // mock sending
 	db.Handlers.Unmarshal.Clear()
 	db.Handlers.UnmarshalMeta.Clear()

+ 42 - 9
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/request_test.go

@@ -7,15 +7,17 @@ import (
 	"io"
 	"io/ioutil"
 	"net/http"
+	"runtime"
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
+
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/stretchr/testify/assert"
+	"github.com/aws/aws-sdk-go/awstesting"
 )
 
 type testData struct {
@@ -74,7 +76,7 @@ func TestRequestRecoverRetry5xx(t *testing.T) {
 		{StatusCode: 200, Body: body(`{"data":"valid"}`)},
 	}
 
-	s := service.New(aws.NewConfig().WithMaxRetries(10))
+	s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
 	s.Handlers.Validate.Clear()
 	s.Handlers.Unmarshal.PushBack(unmarshal)
 	s.Handlers.UnmarshalError.PushBack(unmarshalError)
@@ -100,7 +102,7 @@ func TestRequestRecoverRetry4xxRetryable(t *testing.T) {
 		{StatusCode: 200, Body: body(`{"data":"valid"}`)},
 	}
 
-	s := service.New(aws.NewConfig().WithMaxRetries(10))
+	s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
 	s.Handlers.Validate.Clear()
 	s.Handlers.Unmarshal.PushBack(unmarshal)
 	s.Handlers.UnmarshalError.PushBack(unmarshalError)
@@ -119,7 +121,7 @@ func TestRequestRecoverRetry4xxRetryable(t *testing.T) {
 
 // test that retries don't occur for 4xx status codes with a response type that can't be retried
 func TestRequest4xxUnretryable(t *testing.T) {
-	s := service.New(aws.NewConfig().WithMaxRetries(10))
+	s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
 	s.Handlers.Validate.Clear()
 	s.Handlers.Unmarshal.PushBack(unmarshal)
 	s.Handlers.UnmarshalError.PushBack(unmarshalError)
@@ -155,7 +157,7 @@ func TestRequestExhaustRetries(t *testing.T) {
 		{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
 	}
 
-	s := service.New(aws.NewConfig().WithMaxRetries(aws.DefaultRetries).WithSleepDelay(sleepDelay))
+	s := awstesting.NewClient(aws.NewConfig().WithSleepDelay(sleepDelay))
 	s.Handlers.Validate.Clear()
 	s.Handlers.Unmarshal.PushBack(unmarshal)
 	s.Handlers.UnmarshalError.PushBack(unmarshalError)
@@ -193,7 +195,7 @@ func TestRequestRecoverExpiredCreds(t *testing.T) {
 		{StatusCode: 200, Body: body(`{"data":"valid"}`)},
 	}
 
-	s := service.New(&aws.Config{MaxRetries: aws.Int(10), Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")})
+	s := awstesting.NewClient(&aws.Config{MaxRetries: aws.Int(10), Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")})
 	s.Handlers.Validate.Clear()
 	s.Handlers.Unmarshal.PushBack(unmarshal)
 	s.Handlers.UnmarshalError.PushBack(unmarshalError)
@@ -202,12 +204,12 @@ func TestRequestRecoverExpiredCreds(t *testing.T) {
 	credExpiredAfterRetry := false
 
 	s.Handlers.AfterRetry.PushBack(func(r *request.Request) {
-		credExpiredAfterRetry = r.Service.Config.Credentials.IsExpired()
+		credExpiredAfterRetry = r.Config.Credentials.IsExpired()
 	})
 
 	s.Handlers.Sign.Clear()
 	s.Handlers.Sign.PushBack(func(r *request.Request) {
-		r.Service.Config.Credentials.Get()
+		r.Config.Credentials.Get()
 	})
 	s.Handlers.Send.Clear() // mock sending
 	s.Handlers.Send.PushBack(func(r *request.Request) {
@@ -226,3 +228,34 @@ func TestRequestRecoverExpiredCreds(t *testing.T) {
 	assert.Equal(t, 1, int(r.RetryCount))
 	assert.Equal(t, "valid", out.Data)
 }
+
+func TestMakeAddtoUserAgentHandler(t *testing.T) {
+	fn := request.MakeAddToUserAgentHandler("name", "version", "extra1", "extra2")
+	r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
+	r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
+	fn(r)
+
+	assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"))
+}
+
+func TestMakeAddtoUserAgentFreeFormHandler(t *testing.T) {
+	fn := request.MakeAddToUserAgentFreeFormHandler("name/version (extra1; extra2)")
+	r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
+	r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
+	fn(r)
+
+	assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"))
+}
+
+func TestRequestUserAgent(t *testing.T) {
+	s := awstesting.NewClient(&aws.Config{Region: aws.String("us-east-1")})
+	//	s.Handlers.Validate.Clear()
+
+	req := s.NewRequest(&request.Operation{Name: "Operation"}, nil, &testData{})
+	req.HTTPRequest.Header.Set("User-Agent", "foo/bar")
+	assert.NoError(t, req.Build())
+
+	expectUA := fmt.Sprintf("foo/bar %s/%s (%s; %s; %s)",
+		aws.SDKName, aws.SDKVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH)
+	assert.Equal(t, expectUA, req.HTTPRequest.Header.Get("User-Agent"))
+}

+ 10 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request/retryer.go

@@ -3,6 +3,7 @@ package request
 import (
 	"time"
 
+	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 )
 
@@ -12,13 +13,21 @@ import (
 type Retryer interface {
 	RetryRules(*Request) time.Duration
 	ShouldRetry(*Request) bool
-	MaxRetries() uint
+	MaxRetries() int
+}
+
+// WithRetryer sets a config Retryer value to the given Config returning it
+// for chaining.
+func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
+	cfg.Retryer = retryer
+	return cfg
 }
 
 // retryableCodes is a collection of service response codes which are retry-able
 // without any further action.
 var retryableCodes = map[string]struct{}{
 	"RequestError":                           {},
+	"RequestTimeout":                         {},
 	"ProvisionedThroughputExceededException": {},
 	"Throttling":                             {},
 	"ThrottlingException":                    {},

+ 0 - 133
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/service.go

@@ -1,133 +0,0 @@
-package service
-
-import (
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/http/httputil"
-	"regexp"
-	"time"
-
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/corehandlers"
-	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
-	"github.com/aws/aws-sdk-go/private/endpoints"
-)
-
-// A Service implements the base service request and response handling
-// used by all services.
-type Service struct {
-	serviceinfo.ServiceInfo
-	request.Retryer
-	DefaultMaxRetries uint
-	Handlers          request.Handlers
-}
-
-var schemeRE = regexp.MustCompile("^([^:]+)://")
-
-// New will return a pointer to a new Server object initialized.
-func New(config *aws.Config) *Service {
-	svc := &Service{ServiceInfo: serviceinfo.ServiceInfo{Config: config}}
-	svc.Initialize()
-	return svc
-}
-
-// Initialize initializes the service.
-func (s *Service) Initialize() {
-	if s.Config == nil {
-		s.Config = &aws.Config{}
-	}
-	if s.Config.HTTPClient == nil {
-		s.Config.HTTPClient = http.DefaultClient
-	}
-	if s.Config.SleepDelay == nil {
-		s.Config.SleepDelay = time.Sleep
-	}
-
-	s.Retryer = DefaultRetryer{s}
-	s.DefaultMaxRetries = 3
-	s.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
-	s.Handlers.Build.PushBackNamed(corehandlers.UserAgentHandler)
-	s.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
-	s.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
-	s.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
-	s.Handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
-	if !aws.BoolValue(s.Config.DisableParamValidation) {
-		s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
-	}
-	s.AddDebugHandlers()
-	s.buildEndpoint()
-}
-
-// NewRequest returns a new Request pointer for the service API
-// operation and parameters.
-func (s *Service) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
-	return request.New(s.ServiceInfo, s.Handlers, s.Retryer, operation, params, data)
-}
-
-// buildEndpoint builds the endpoint values the service will use to make requests with.
-func (s *Service) buildEndpoint() {
-	if aws.StringValue(s.Config.Endpoint) != "" {
-		s.Endpoint = *s.Config.Endpoint
-	} else if s.Endpoint == "" {
-		s.Endpoint, s.SigningRegion =
-			endpoints.EndpointForRegion(s.ServiceName, aws.StringValue(s.Config.Region))
-	}
-
-	if s.Endpoint != "" && !schemeRE.MatchString(s.Endpoint) {
-		scheme := "https"
-		if aws.BoolValue(s.Config.DisableSSL) {
-			scheme = "http"
-		}
-		s.Endpoint = scheme + "://" + s.Endpoint
-	}
-}
-
-// AddDebugHandlers injects debug logging handlers into the service to log request
-// debug information.
-func (s *Service) AddDebugHandlers() {
-	if !s.Config.LogLevel.AtLeast(aws.LogDebug) {
-		return
-	}
-
-	s.Handlers.Send.PushFront(logRequest)
-	s.Handlers.Send.PushBack(logResponse)
-}
-
-const logReqMsg = `DEBUG: Request %s/%s Details:
----[ REQUEST POST-SIGN ]-----------------------------
-%s
------------------------------------------------------`
-
-func logRequest(r *request.Request) {
-	logBody := r.Service.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
-	dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
-
-	if logBody {
-		// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
-		// Body as a NoOpCloser and will not be reset after read by the HTTP
-		// client reader.
-		r.Body.Seek(r.BodyStart, 0)
-		r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
-	}
-
-	r.Service.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.Service.ServiceName, r.Operation.Name, string(dumpedBody)))
-}
-
-const logRespMsg = `DEBUG: Response %s/%s Details:
----[ RESPONSE ]--------------------------------------
-%s
------------------------------------------------------`
-
-func logResponse(r *request.Request) {
-	var msg = "no reponse data"
-	if r.HTTPResponse != nil {
-		logBody := r.Service.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
-		dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
-		msg = string(dumpedBody)
-	} else if r.Error != nil {
-		msg = r.Error.Error()
-	}
-	r.Service.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.Service.ServiceName, r.Operation.Name, msg))
-}

+ 0 - 15
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/service/serviceinfo/service_info.go

@@ -1,15 +0,0 @@
-package serviceinfo
-
-import "github.com/aws/aws-sdk-go/aws"
-
-// ServiceInfo wraps immutable data from the service.Service structure.
-type ServiceInfo struct {
-	Config        *aws.Config
-	ServiceName   string
-	APIVersion    string
-	Endpoint      string
-	SigningName   string
-	SigningRegion string
-	JSONVersion   string
-	TargetPrefix  string
-}

+ 105 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session.go

@@ -0,0 +1,105 @@
+// Package session provides a way to create service clients with shared configuration
+// and handlers.
+package session
+
+import (
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/corehandlers"
+	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/endpoints"
+)
+
+// A Session provides a central location to create service clients from and
+// store configurations and request handlers for those services.
+//
+// Sessions are safe to create service clients concurrently, but it is not safe
+// to mutate the session concurrently.
+type Session struct {
+	Config   *aws.Config
+	Handlers request.Handlers
+}
+
+// New creates a new instance of the handlers merging in the provided Configs
+// on top of the SDK's default configurations. Once the session is created it
+// can be mutated to modify Configs or Handlers. The session is safe to be read
+// concurrently, but it should not be written to concurrently.
+//
+// Example:
+//     // Create a session with the default config and request handlers.
+//     sess := session.New()
+//
+//     // Create a session with a custom region
+//     sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
+//
+//     // Create a session, and add additional handlers for all service
+//     // clients created with the session to inherit. Adds logging handler.
+//     sess := session.New()
+//     sess.Handlers.Send.PushFront(func(r *request.Request) {
+//          // Log every request made and its payload
+//          logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
+//     })
+//
+//     // Create a S3 client instance from a session
+//     sess := session.New()
+//     svc := s3.New(sess)
+func New(cfgs ...*aws.Config) *Session {
+	def := defaults.Get()
+	s := &Session{
+		Config:   def.Config,
+		Handlers: def.Handlers,
+	}
+	s.Config.MergeIn(cfgs...)
+
+	initHandlers(s)
+
+	return s
+}
+
+func initHandlers(s *Session) {
+	// Add the Validate parameter handler if it is not disabled.
+	s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
+	if !aws.BoolValue(s.Config.DisableParamValidation) {
+		s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
+	}
+}
+
+// Copy creates and returns a copy of the current session, coping the config
+// and handlers. If any additional configs are provided they will be merged
+// on top of the session's copied config.
+//
+// Example:
+//     // Create a copy of the current session, configured for the us-west-2 region.
+//     sess.Copy(&aws.Config{Region: aws.String("us-west-2"})
+func (s *Session) Copy(cfgs ...*aws.Config) *Session {
+	newSession := &Session{
+		Config:   s.Config.Copy(cfgs...),
+		Handlers: s.Handlers.Copy(),
+	}
+
+	initHandlers(newSession)
+
+	return newSession
+}
+
+// ClientConfig satisfies the client.ConfigProvider interface and is used to
+// configure the service client instances. Passing the Session to the service
+// client's constructor (New) will use this method to configure the client.
+//
+// Example:
+//     sess := session.New()
+//     s3.New(sess)
+func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
+	s = s.Copy(cfgs...)
+	endpoint, signingRegion := endpoints.NormalizeEndpoint(
+		aws.StringValue(s.Config.Endpoint), serviceName,
+		aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL))
+
+	return client.Config{
+		Config:        s.Config,
+		Handlers:      s.Handlers,
+		Endpoint:      endpoint,
+		SigningRegion: signingRegion,
+	}
+}

+ 20 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/session/session_test.go

@@ -0,0 +1,20 @@
+package session_test
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/session"
+)
+
+func TestNewDefaultSession(t *testing.T) {
+	s := session.New(&aws.Config{Region: aws.String("region")})
+
+	assert.Equal(t, "region", *s.Config.Region)
+	assert.Equal(t, http.DefaultClient, s.Config.HTTPClient)
+	assert.NotNil(t, s.Config.Logger)
+	assert.Equal(t, aws.LogOff, *s.Config.LogLevel)
+}

+ 1 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/types.go

@@ -5,7 +5,7 @@ import (
 	"sync"
 )
 
-// ReadSeekCloser wraps a io.Reader returning a ReaderSeakerCloser
+// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser
 func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
 	return ReaderSeekerCloser{r}
 }

+ 1 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/version.go

@@ -5,4 +5,4 @@ package aws
 const SDKName = "aws-sdk-go"
 
 // SDKVersion is the version of this SDK
-const SDKVersion = "0.9.16"
+const SDKVersion = "1.0.0"

+ 38 - 4
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go

@@ -4,11 +4,27 @@ package endpoints
 //go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go
 //go:generate gofmt -s -w endpoints_map.go
 
-import "strings"
+import (
+	"fmt"
+	"regexp"
+	"strings"
+)
+
+// NormalizeEndpoint takes and endpoint and service API information to return a
+// normalized endpoint and signing region.  If the endpoint is not an empty string
+// the service name and region will be used to look up the service's API endpoint.
+// If the endpoint is provided the scheme will be added if it is not present.
+func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (normEndpoint, signingRegion string) {
+	if endpoint == "" {
+		return EndpointForRegion(serviceName, region, disableSSL)
+	}
+
+	return AddScheme(endpoint, disableSSL), ""
+}
 
 // EndpointForRegion returns an endpoint and its signing region for a service and region.
 // if the service and region pair are not found endpoint and signingRegion will be empty.
-func EndpointForRegion(svcName, region string) (endpoint, signingRegion string) {
+func EndpointForRegion(svcName, region string, disableSSL bool) (endpoint, signingRegion string) {
 	derivedKeys := []string{
 		region + "/" + svcName,
 		region + "/*",
@@ -24,8 +40,26 @@ func EndpointForRegion(svcName, region string) (endpoint, signingRegion string)
 
 			endpoint = ep
 			signingRegion = val.SigningRegion
-			return
+			break
 		}
 	}
-	return
+
+	return AddScheme(endpoint, disableSSL), signingRegion
+}
+
+// Regular expression to determine if the endpoint string is prefixed with a scheme.
+var schemeRE = regexp.MustCompile("^([^:]+)://")
+
+// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
+// scheme. If disableSSL is true HTTP will be added instead of the default HTTPS.
+func AddScheme(endpoint string, disableSSL bool) string {
+	if endpoint != "" && !schemeRE.MatchString(endpoint) {
+		scheme := "https"
+		if disableSSL {
+			scheme = "http"
+		}
+		endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
+	}
+
+	return endpoint
 }

+ 8 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json

@@ -29,6 +29,10 @@
       "endpoint": "",
       "signingRegion": "us-east-1"
     },
+    "*/ec2metadata": {
+      "endpoint": "http://169.254.169.254/latest",
+      "signingRegion": "us-east-1"
+    },
     "*/iam": {
       "endpoint": "iam.amazonaws.com",
       "signingRegion": "us-east-1"
@@ -45,6 +49,10 @@
       "endpoint": "sts.amazonaws.com",
       "signingRegion": "us-east-1"
     },
+    "*/waf": {
+      "endpoint": "waf.amazonaws.com",
+      "signingRegion": "us-east-1"
+    },
     "us-east-1/sdb": {
       "endpoint": "sdb.amazonaws.com",
       "signingRegion": "us-east-1"

+ 8 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go

@@ -30,6 +30,10 @@ var endpointsMap = endpointStruct{
 			Endpoint:      "",
 			SigningRegion: "us-east-1",
 		},
+		"*/ec2metadata": {
+			Endpoint:      "http://169.254.169.254/latest",
+			SigningRegion: "us-east-1",
+		},
 		"*/iam": {
 			Endpoint:      "iam.amazonaws.com",
 			SigningRegion: "us-east-1",
@@ -46,6 +50,10 @@ var endpointsMap = endpointStruct{
 			Endpoint:      "sts.amazonaws.com",
 			SigningRegion: "us-east-1",
 		},
+		"*/waf": {
+			Endpoint:      "waf.amazonaws.com",
+			SigningRegion: "us-east-1",
+		},
 		"ap-northeast-1/s3": {
 			Endpoint: "s3-{region}.amazonaws.com",
 		},

+ 20 - 7
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/endpoints/endpoints_test.go

@@ -1,28 +1,41 @@
-package endpoints
+package endpoints_test
 
 import (
+	"fmt"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+
+	"github.com/aws/aws-sdk-go/private/endpoints"
 )
 
+func TestGenericEndpoint(t *testing.T) {
+	name := "service"
+	region := "mock-region-1"
+
+	ep, sr := endpoints.EndpointForRegion(name, region, false)
+	assert.Equal(t, fmt.Sprintf("https://%s.%s.amazonaws.com", name, region), ep)
+	assert.Empty(t, sr)
+}
+
 func TestGlobalEndpoints(t *testing.T) {
 	region := "mock-region-1"
-	svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts"}
+	svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "waf"}
 
 	for _, name := range svcs {
-		ep, sr := EndpointForRegion(name, region)
-		assert.Equal(t, name+".amazonaws.com", ep)
+		ep, sr := endpoints.EndpointForRegion(name, region, false)
+		assert.Equal(t, fmt.Sprintf("https://%s.amazonaws.com", name), ep)
 		assert.Equal(t, "us-east-1", sr)
 	}
 }
 
 func TestServicesInCN(t *testing.T) {
 	region := "cn-north-1"
-	svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "s3"}
+	svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "s3", "waf"}
 
 	for _, name := range svcs {
-		ep, _ := EndpointForRegion(name, region)
-		assert.Equal(t, name+"."+region+".amazonaws.com.cn", ep)
+		ep, sr := endpoints.EndpointForRegion(name, region, false)
+		assert.Equal(t, fmt.Sprintf("https://%s.%s.amazonaws.com.cn", name, region), ep)
+		assert.Empty(t, sr)
 	}
 }

+ 1 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build.go

@@ -15,7 +15,7 @@ import (
 func Build(r *request.Request) {
 	body := url.Values{
 		"Action":  {r.Operation.Name},
-		"Version": {r.Service.APIVersion},
+		"Version": {r.ClientInfo.APIVersion},
 	}
 	if err := queryutil.Parse(body, r.Params, true); err != nil {
 		r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)

+ 2 - 2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build_bench_test.go

@@ -7,7 +7,7 @@ import (
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
+	"github.com/aws/aws-sdk-go/awstesting"
 	"github.com/aws/aws-sdk-go/private/protocol/ec2query"
 	"github.com/aws/aws-sdk-go/service/ec2"
 )
@@ -67,7 +67,7 @@ func BenchmarkEC2QueryBuild_Simple_ec2AttachNetworkInterface(b *testing.B) {
 }
 
 func benchEC2QueryBuild(b *testing.B, opName string, params interface{}) {
-	svc := service.New(nil)
+	svc := awstesting.NewClient()
 	svc.ServiceName = "ec2"
 	svc.APIVersion = "2015-04-15"
 

+ 316 - 147
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/build_test.go

@@ -12,10 +12,10 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
+	"github.com/aws/aws-sdk-go/aws/session"
 	"github.com/aws/aws-sdk-go/awstesting"
 	"github.com/aws/aws-sdk-go/private/protocol/ec2query"
 	"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
@@ -35,30 +35,52 @@ var _ = ioutil.Discard
 var _ = util.Trim("")
 var _ = url.Values{}
 var _ = io.EOF
+var _ = aws.String
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService1ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService1ProtocolTest client.
-func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice1protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService1ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService1ProtocolTest client from just a session.
+//     svc := inputservice1protocoltest.New(mySession)
+//
+//     // Create a InputService1ProtocolTest client with additional configuration
+//     svc := inputservice1protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService1ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService1ProtocolTest {
+	c := p.ClientConfig("inputservice1protocoltest", cfgs...)
+	return newInputService1ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService1ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService1ProtocolTest {
+	svc := &InputService1ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice1protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService1ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService1ProtocolTest operation and runs any
@@ -113,29 +135,50 @@ type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService2ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService2ProtocolTest client.
-func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice2protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService2ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService2ProtocolTest client from just a session.
+//     svc := inputservice2protocoltest.New(mySession)
+//
+//     // Create a InputService2ProtocolTest client with additional configuration
+//     svc := inputservice2protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService2ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService2ProtocolTest {
+	c := p.ClientConfig("inputservice2protocoltest", cfgs...)
+	return newInputService2ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService2ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService2ProtocolTest {
+	svc := &InputService2ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice2protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService2ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService2ProtocolTest operation and runs any
@@ -192,29 +235,50 @@ type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService3ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService3ProtocolTest client.
-func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice3protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService3ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService3ProtocolTest client from just a session.
+//     svc := inputservice3protocoltest.New(mySession)
+//
+//     // Create a InputService3ProtocolTest client with additional configuration
+//     svc := inputservice3protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService3ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService3ProtocolTest {
+	c := p.ClientConfig("inputservice3protocoltest", cfgs...)
+	return newInputService3ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService3ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService3ProtocolTest {
+	svc := &InputService3ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice3protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService3ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService3ProtocolTest operation and runs any
@@ -277,29 +341,50 @@ type metadataInputService3TestShapeStructType struct {
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService4ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService4ProtocolTest client.
-func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice4protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService4ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService4ProtocolTest client from just a session.
+//     svc := inputservice4protocoltest.New(mySession)
+//
+//     // Create a InputService4ProtocolTest client with additional configuration
+//     svc := inputservice4protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService4ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService4ProtocolTest {
+	c := p.ClientConfig("inputservice4protocoltest", cfgs...)
+	return newInputService4ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService4ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService4ProtocolTest {
+	svc := &InputService4ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice4protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService4ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService4ProtocolTest operation and runs any
@@ -352,29 +437,50 @@ type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService5ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService5ProtocolTest client.
-func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice5protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService5ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService5ProtocolTest client from just a session.
+//     svc := inputservice5protocoltest.New(mySession)
+//
+//     // Create a InputService5ProtocolTest client with additional configuration
+//     svc := inputservice5protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService5ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService5ProtocolTest {
+	c := p.ClientConfig("inputservice5protocoltest", cfgs...)
+	return newInputService5ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService5ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService5ProtocolTest {
+	svc := &InputService5ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice5protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService5ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService5ProtocolTest operation and runs any
@@ -427,29 +533,50 @@ type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService6ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService6ProtocolTest client.
-func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice6protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService6ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService6ProtocolTest client from just a session.
+//     svc := inputservice6protocoltest.New(mySession)
+//
+//     // Create a InputService6ProtocolTest client with additional configuration
+//     svc := inputservice6protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService6ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService6ProtocolTest {
+	c := p.ClientConfig("inputservice6protocoltest", cfgs...)
+	return newInputService6ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService6ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService6ProtocolTest {
+	svc := &InputService6ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice6protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService6ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService6ProtocolTest operation and runs any
@@ -502,29 +629,50 @@ type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService7ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService7ProtocolTest client.
-func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice7protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService7ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService7ProtocolTest client from just a session.
+//     svc := inputservice7protocoltest.New(mySession)
+//
+//     // Create a InputService7ProtocolTest client with additional configuration
+//     svc := inputservice7protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService7ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService7ProtocolTest {
+	c := p.ClientConfig("inputservice7protocoltest", cfgs...)
+	return newInputService7ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService7ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService7ProtocolTest {
+	svc := &InputService7ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice7protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService7ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService7ProtocolTest operation and runs any
@@ -577,29 +725,50 @@ type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type InputService8ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new InputService8ProtocolTest client.
-func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "inputservice8protocoltest",
-			APIVersion:  "2014-01-01",
-		},
+// New creates a new instance of the InputService8ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a InputService8ProtocolTest client from just a session.
+//     svc := inputservice8protocoltest.New(mySession)
+//
+//     // Create a InputService8ProtocolTest client with additional configuration
+//     svc := inputservice8protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewInputService8ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService8ProtocolTest {
+	c := p.ClientConfig("inputservice8protocoltest", cfgs...)
+	return newInputService8ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newInputService8ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *InputService8ProtocolTest {
+	svc := &InputService8ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "inputservice8protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2014-01-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &InputService8ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a InputService8ProtocolTest operation and runs any
@@ -657,8 +826,8 @@ type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct
 //
 
 func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
-	svc := NewInputService1ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService1ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService1TestShapeInputService1TestCaseOperation1Input{
 		Bar: aws.String("val2"),
@@ -684,8 +853,8 @@ func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
 }
 
 func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedToMembersCase1(t *testing.T) {
-	svc := NewInputService2ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService2ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService2TestShapeInputService2TestCaseOperation1Input{
 		Bar:  aws.String("val2"),
@@ -712,8 +881,8 @@ func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedTo
 }
 
 func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
-	svc := NewInputService3ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService3ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService3TestShapeInputService3TestCaseOperation1Input{
 		StructArg: &InputService3TestShapeStructType{
@@ -740,8 +909,8 @@ func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
 }
 
 func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
-	svc := NewInputService4ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService4ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService4TestShapeInputService4TestCaseOperation1Input{
 		ListArg: []*string{
@@ -770,8 +939,8 @@ func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
 }
 
 func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *testing.T) {
-	svc := NewInputService5ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService5ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService5TestShapeInputService5TestCaseOperation1Input{
 		ListArg: []*string{
@@ -800,8 +969,8 @@ func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *te
 }
 
 func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testing.T) {
-	svc := NewInputService6ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService6ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService6TestShapeInputService6TestCaseOperation1Input{
 		ListArg: []*string{
@@ -830,8 +999,8 @@ func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testi
 }
 
 func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
-	svc := NewInputService7ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService7ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService7TestShapeInputService7TestCaseOperation1Input{
 		BlobArg: []byte("foo"),
@@ -856,8 +1025,8 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
 }
 
 func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
-	svc := NewInputService8ProtocolTest(nil)
-	svc.Endpoint = "https://test"
+	sess := session.New()
+	svc := NewInputService8ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	input := &InputService8TestShapeInputService8TestCaseOperation1Input{
 		TimeArg: aws.Time(time.Unix(1422172800, 0)),

+ 433 - 139
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/ec2query/unmarshal_test.go

@@ -12,10 +12,10 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
+	"github.com/aws/aws-sdk-go/aws/session"
 	"github.com/aws/aws-sdk-go/awstesting"
 	"github.com/aws/aws-sdk-go/private/protocol/ec2query"
 	"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
@@ -35,30 +35,52 @@ var _ = ioutil.Discard
 var _ = util.Trim("")
 var _ = url.Values{}
 var _ = io.EOF
+var _ = aws.String
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService1ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService1ProtocolTest client.
-func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice1protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService1ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService1ProtocolTest client from just a session.
+//     svc := outputservice1protocoltest.New(mySession)
+//
+//     // Create a OutputService1ProtocolTest client with additional configuration
+//     svc := outputservice1protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService1ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService1ProtocolTest {
+	c := p.ClientConfig("outputservice1protocoltest", cfgs...)
+	return newOutputService1ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService1ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService1ProtocolTest {
+	svc := &OutputService1ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice1protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService1ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService1ProtocolTest operation and runs any
@@ -125,29 +147,50 @@ type metadataOutputService1TestShapeOutputService1TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService2ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService2ProtocolTest client.
-func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice2protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService2ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService2ProtocolTest client from just a session.
+//     svc := outputservice2protocoltest.New(mySession)
+//
+//     // Create a OutputService2ProtocolTest client with additional configuration
+//     svc := outputservice2protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService2ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService2ProtocolTest {
+	c := p.ClientConfig("outputservice2protocoltest", cfgs...)
+	return newOutputService2ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService2ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService2ProtocolTest {
+	svc := &OutputService2ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice2protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService2ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService2ProtocolTest operation and runs any
@@ -200,29 +243,50 @@ type metadataOutputService2TestShapeOutputService2TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService3ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService3ProtocolTest client.
-func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice3protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService3ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService3ProtocolTest client from just a session.
+//     svc := outputservice3protocoltest.New(mySession)
+//
+//     // Create a OutputService3ProtocolTest client with additional configuration
+//     svc := outputservice3protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService3ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService3ProtocolTest {
+	c := p.ClientConfig("outputservice3protocoltest", cfgs...)
+	return newOutputService3ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService3ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService3ProtocolTest {
+	svc := &OutputService3ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice3protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService3ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService3ProtocolTest operation and runs any
@@ -275,29 +339,50 @@ type metadataOutputService3TestShapeOutputService3TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService4ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService4ProtocolTest client.
-func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice4protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService4ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService4ProtocolTest client from just a session.
+//     svc := outputservice4protocoltest.New(mySession)
+//
+//     // Create a OutputService4ProtocolTest client with additional configuration
+//     svc := outputservice4protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService4ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService4ProtocolTest {
+	c := p.ClientConfig("outputservice4protocoltest", cfgs...)
+	return newOutputService4ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService4ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService4ProtocolTest {
+	svc := &OutputService4ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice4protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService4ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService4ProtocolTest operation and runs any
@@ -350,29 +435,50 @@ type metadataOutputService4TestShapeOutputService4TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService5ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService5ProtocolTest client.
-func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice5protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService5ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService5ProtocolTest client from just a session.
+//     svc := outputservice5protocoltest.New(mySession)
+//
+//     // Create a OutputService5ProtocolTest client with additional configuration
+//     svc := outputservice5protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService5ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService5ProtocolTest {
+	c := p.ClientConfig("outputservice5protocoltest", cfgs...)
+	return newOutputService5ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService5ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService5ProtocolTest {
+	svc := &OutputService5ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice5protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService5ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService5ProtocolTest operation and runs any
@@ -425,29 +531,50 @@ type metadataOutputService5TestShapeOutputService5TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService6ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService6ProtocolTest client.
-func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice6protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService6ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService6ProtocolTest client from just a session.
+//     svc := outputservice6protocoltest.New(mySession)
+//
+//     // Create a OutputService6ProtocolTest client with additional configuration
+//     svc := outputservice6protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService6ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService6ProtocolTest {
+	c := p.ClientConfig("outputservice6protocoltest", cfgs...)
+	return newOutputService6ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService6ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService6ProtocolTest {
+	svc := &OutputService6ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice6protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService6ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService6ProtocolTest operation and runs any
@@ -510,29 +637,50 @@ type metadataOutputService6TestShapeStructureType struct {
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService7ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService7ProtocolTest client.
-func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice7protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService7ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService7ProtocolTest client from just a session.
+//     svc := outputservice7protocoltest.New(mySession)
+//
+//     // Create a OutputService7ProtocolTest client with additional configuration
+//     svc := outputservice7protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService7ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService7ProtocolTest {
+	c := p.ClientConfig("outputservice7protocoltest", cfgs...)
+	return newOutputService7ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService7ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService7ProtocolTest {
+	svc := &OutputService7ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice7protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService7ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService7ProtocolTest operation and runs any
@@ -585,29 +733,50 @@ type metadataOutputService7TestShapeOutputService7TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type OutputService8ProtocolTest struct {
-	*service.Service
+	*client.Client
 }
 
-// New returns a new OutputService8ProtocolTest client.
-func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTest {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "outputservice8protocoltest",
-			APIVersion:  "",
-		},
+// New creates a new instance of the OutputService8ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService8ProtocolTest client from just a session.
+//     svc := outputservice8protocoltest.New(mySession)
+//
+//     // Create a OutputService8ProtocolTest client with additional configuration
+//     svc := outputservice8protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService8ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService8ProtocolTest {
+	c := p.ClientConfig("outputservice8protocoltest", cfgs...)
+	return newOutputService8ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService8ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService8ProtocolTest {
+	svc := &OutputService8ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice8protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	return &OutputService8ProtocolTest{service}
+	return svc
 }
 
 // newRequest creates a new request for a OutputService8ProtocolTest operation and runs any
@@ -660,12 +829,109 @@ type metadataOutputService8TestShapeOutputService8TestCaseOperation1Output struc
 	SDKShapeTraits bool `type:"structure"`
 }
 
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
+type OutputService9ProtocolTest struct {
+	*client.Client
+}
+
+// New creates a new instance of the OutputService9ProtocolTest client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a OutputService9ProtocolTest client from just a session.
+//     svc := outputservice9protocoltest.New(mySession)
+//
+//     // Create a OutputService9ProtocolTest client with additional configuration
+//     svc := outputservice9protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func NewOutputService9ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService9ProtocolTest {
+	c := p.ClientConfig("outputservice9protocoltest", cfgs...)
+	return newOutputService9ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newOutputService9ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *OutputService9ProtocolTest {
+	svc := &OutputService9ProtocolTest{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   "outputservice9protocoltest",
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "",
+			},
+			handlers,
+		),
+	}
+
+	// Handlers
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+
+	return svc
+}
+
+// newRequest creates a new request for a OutputService9ProtocolTest operation and runs any
+// custom request initialization.
+func (c *OutputService9ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
+	req := c.NewRequest(op, params, data)
+
+	return req
+}
+
+const opOutputService9TestCaseOperation1 = "OperationName"
+
+// OutputService9TestCaseOperation1Request generates a request for the OutputService9TestCaseOperation1 operation.
+func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1Request(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (req *request.Request, output *OutputService9TestShapeOutputService9TestCaseOperation1Output) {
+	op := &request.Operation{
+		Name: opOutputService9TestCaseOperation1,
+	}
+
+	if input == nil {
+		input = &OutputService9TestShapeOutputService9TestCaseOperation1Input{}
+	}
+
+	req = c.newRequest(op, input, output)
+	output = &OutputService9TestShapeOutputService9TestCaseOperation1Output{}
+	req.Data = output
+	return
+}
+
+func (c *OutputService9ProtocolTest) OutputService9TestCaseOperation1(input *OutputService9TestShapeOutputService9TestCaseOperation1Input) (*OutputService9TestShapeOutputService9TestCaseOperation1Output, error) {
+	req, out := c.OutputService9TestCaseOperation1Request(input)
+	err := req.Send()
+	return out, err
+}
+
+type OutputService9TestShapeOutputService9TestCaseOperation1Input struct {
+	metadataOutputService9TestShapeOutputService9TestCaseOperation1Input `json:"-" xml:"-"`
+}
+
+type metadataOutputService9TestShapeOutputService9TestCaseOperation1Input struct {
+	SDKShapeTraits bool `type:"structure"`
+}
+
+type OutputService9TestShapeOutputService9TestCaseOperation1Output struct {
+	Foo *string `type:"string"`
+
+	metadataOutputService9TestShapeOutputService9TestCaseOperation1Output `json:"-" xml:"-"`
+}
+
+type metadataOutputService9TestShapeOutputService9TestCaseOperation1Output struct {
+	SDKShapeTraits bool `type:"structure"`
+}
+
 //
 // Tests begin here
 //
 
 func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
-	svc := NewOutputService1ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService1ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><Str>myname</Str><FooNum>123</FooNum><FalseBool>false</FalseBool><TrueBool>true</TrueBool><Float>1.2</Float><Double>1.3</Double><Long>200</Long><Char>a</Char><RequestId>request-id</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService1TestCaseOperation1Request(nil)
@@ -692,7 +958,8 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
 }
 
 func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
-	svc := NewOutputService2ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService2ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><Blob>dmFsdWU=</Blob><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService2TestCaseOperation1Request(nil)
@@ -712,7 +979,8 @@ func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
 }
 
 func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
-	svc := NewOutputService3ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService3ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><member>abc</member><member>123</member></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService3TestCaseOperation1Request(nil)
@@ -733,7 +1001,8 @@ func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
 }
 
 func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
-	svc := NewOutputService4ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService4ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><item>abc</item><item>123</item></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService4TestCaseOperation1Request(nil)
@@ -754,7 +1023,8 @@ func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
 }
 
 func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
-	svc := NewOutputService5ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService5ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember>abc</ListMember><ListMember>123</ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService5TestCaseOperation1Request(nil)
@@ -775,7 +1045,8 @@ func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
 }
 
 func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
-	svc := NewOutputService6ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService6ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><Map><entry><key>qux</key><value><foo>bar</foo></value></entry><entry><key>baz</key><value><foo>bam</foo></value></entry></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService6TestCaseOperation1Request(nil)
@@ -796,7 +1067,8 @@ func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
 }
 
 func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
-	svc := NewOutputService7ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService7ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><Map><key>qux</key><value>bar</value></Map><Map><key>baz</key><value>bam</value></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService7TestCaseOperation1Request(nil)
@@ -817,7 +1089,8 @@ func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
 }
 
 func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
-	svc := NewOutputService8ProtocolTest(nil)
+	sess := session.New()
+	svc := NewOutputService8ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
 
 	buf := bytes.NewReader([]byte("<OperationNameResponse><Map><foo>qux</foo><bar>bar</bar></Map><Map><foo>baz</foo><bar>bam</bar></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
 	req, out := svc.OutputService8TestCaseOperation1Request(nil)
@@ -836,3 +1109,24 @@ func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
 	assert.Equal(t, "bar", *out.Map["qux"])
 
 }
+
+func TestOutputService9ProtocolTestEmptyStringCase1(t *testing.T) {
+	sess := session.New()
+	svc := NewOutputService9ProtocolTest(sess, &aws.Config{Endpoint: aws.String("https://test")})
+
+	buf := bytes.NewReader([]byte("<OperationNameResponse><Foo/><RequestId>requestid</RequestId></OperationNameResponse>"))
+	req, out := svc.OutputService9TestCaseOperation1Request(nil)
+	req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
+
+	// set headers
+
+	// unmarshal response
+	ec2query.UnmarshalMeta(req)
+	ec2query.Unmarshal(req)
+	assert.NoError(t, req.Error)
+
+	// assert response
+	assert.NotNil(t, out) // ensure out variable is used
+	assert.Equal(t, "", *out.Foo)
+
+}

+ 1 - 1
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/build.go

@@ -15,7 +15,7 @@ import (
 func Build(r *request.Request) {
 	body := url.Values{
 		"Action":  {r.Operation.Name},
-		"Version": {r.Service.APIVersion},
+		"Version": {r.ClientInfo.APIVersion},
 	}
 	if err := queryutil.Parse(body, r.Params, false); err != nil {
 		r.Error = awserr.New("SerializationError", "failed encoding Query request", err)

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 539 - 196
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/build_test.go


+ 2 - 2
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go

@@ -72,7 +72,7 @@ func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix stri
 			continue // ignore unexported fields
 		}
 
-		value := elemOf(value.Field(i))
+		elemValue := elemOf(value.Field(i))
 		field := t.Field(i)
 		var name string
 
@@ -97,7 +97,7 @@ func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix stri
 			name = prefix + "." + name
 		}
 
-		if err := q.parseValue(v, value, name, field.Tag); err != nil {
+		if err := q.parseValue(v, elemValue, name, field.Tag); err != nil {
 			return err
 		}
 	}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 620 - 228
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_test.go


+ 3 - 4
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/functional_test.go

@@ -5,16 +5,15 @@ import (
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
+
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/awstesting/unit"
 	"github.com/aws/aws-sdk-go/service/s3"
-	"github.com/stretchr/testify/assert"
 )
 
-var _ = unit.Imported
-
 func TestPresignHandler(t *testing.T) {
-	svc := s3.New(nil)
+	svc := s3.New(unit.Session)
 	req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
 		Bucket:             aws.String("bucket"),
 		Key:                aws.String("key"),

+ 8 - 8
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/v4.go

@@ -67,18 +67,18 @@ type signer struct {
 func Sign(req *request.Request) {
 	// If the request does not need to be signed ignore the signing of the
 	// request if the AnonymousCredentials object is used.
-	if req.Service.Config.Credentials == credentials.AnonymousCredentials {
+	if req.Config.Credentials == credentials.AnonymousCredentials {
 		return
 	}
 
-	region := req.Service.SigningRegion
+	region := req.ClientInfo.SigningRegion
 	if region == "" {
-		region = aws.StringValue(req.Service.Config.Region)
+		region = aws.StringValue(req.Config.Region)
 	}
 
-	name := req.Service.SigningName
+	name := req.ClientInfo.SigningName
 	if name == "" {
-		name = req.Service.ServiceName
+		name = req.ClientInfo.ServiceName
 	}
 
 	s := signer{
@@ -89,9 +89,9 @@ func Sign(req *request.Request) {
 		Body:        req.Body,
 		ServiceName: name,
 		Region:      region,
-		Credentials: req.Service.Config.Credentials,
-		Debug:       req.Service.Config.LogLevel.Value(),
-		Logger:      req.Service.Config.Logger,
+		Credentials: req.Config.Credentials,
+		Debug:       req.Config.LogLevel.Value(),
+		Logger:      req.Config.Logger,
 	}
 
 	req.Error = s.sign()

+ 13 - 8
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/signer/v4/v4_test.go

@@ -6,11 +6,12 @@ import (
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
+
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/credentials"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/stretchr/testify/assert"
+	"github.com/aws/aws-sdk-go/awstesting"
 )
 
 func buildSigner(serviceName string, region string, signTime time.Time, expireTime time.Duration, body string) signer {
@@ -118,7 +119,7 @@ func TestSignPrecomputedBodyChecksum(t *testing.T) {
 }
 
 func TestAnonymousCredentials(t *testing.T) {
-	svc := service.New(&aws.Config{Credentials: credentials.AnonymousCredentials})
+	svc := awstesting.NewClient(&aws.Config{Credentials: credentials.AnonymousCredentials})
 	r := svc.NewRequest(
 		&request.Operation{
 			Name:       "BatchGetItem",
@@ -142,7 +143,7 @@ func TestAnonymousCredentials(t *testing.T) {
 }
 
 func TestIgnoreResignRequestWithValidCreds(t *testing.T) {
-	svc := service.New(&aws.Config{
+	svc := awstesting.NewClient(&aws.Config{
 		Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
 		Region:      aws.String("us-west-2"),
 	})
@@ -164,7 +165,7 @@ func TestIgnoreResignRequestWithValidCreds(t *testing.T) {
 }
 
 func TestIgnorePreResignRequestWithValidCreds(t *testing.T) {
-	svc := service.New(&aws.Config{
+	svc := awstesting.NewClient(&aws.Config{
 		Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
 		Region:      aws.String("us-west-2"),
 	})
@@ -188,7 +189,7 @@ func TestIgnorePreResignRequestWithValidCreds(t *testing.T) {
 
 func TestResignRequestExpiredCreds(t *testing.T) {
 	creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
-	svc := service.New(&aws.Config{Credentials: creds})
+	svc := awstesting.NewClient(&aws.Config{Credentials: creds})
 	r := svc.NewRequest(
 		&request.Operation{
 			Name:       "BatchGetItem",
@@ -208,9 +209,13 @@ func TestResignRequestExpiredCreds(t *testing.T) {
 }
 
 func TestPreResignRequestExpiredCreds(t *testing.T) {
-	provider := &credentials.StaticProvider{credentials.Value{"AKID", "SECRET", "SESSION"}}
+	provider := &credentials.StaticProvider{Value: credentials.Value{
+		AccessKeyID:     "AKID",
+		SecretAccessKey: "SECRET",
+		SessionToken:    "SESSION",
+	}}
 	creds := credentials.NewCredentials(provider)
-	svc := service.New(&aws.Config{Credentials: creds})
+	svc := awstesting.NewClient(&aws.Config{Credentials: creds})
 	r := svc.NewRequest(
 		&request.Operation{
 			Name:       "BatchGetItem",

+ 136 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/waiter/waiter.go

@@ -0,0 +1,136 @@
+package waiter
+
+import (
+	"fmt"
+	"reflect"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// A Config provides a collection of configuration values to setup a generated
+// waiter code with.
+type Config struct {
+	Name        string
+	Delay       int
+	MaxAttempts int
+	Operation   string
+	Acceptors   []WaitAcceptor
+}
+
+// A WaitAcceptor provides the information needed to wait for an API operation
+// to complete.
+type WaitAcceptor struct {
+	Expected interface{}
+	Matcher  string
+	State    string
+	Argument string
+}
+
+// A Waiter provides waiting for an operation to complete.
+type Waiter struct {
+	Config
+	Client interface{}
+	Input  interface{}
+}
+
+// Wait waits for an operation to complete, expire max attempts, or fail. Error
+// is returned if the operation fails.
+func (w *Waiter) Wait() error {
+	client := reflect.ValueOf(w.Client)
+	in := reflect.ValueOf(w.Input)
+	method := client.MethodByName(w.Config.Operation + "Request")
+
+	for i := 0; i < w.MaxAttempts; i++ {
+		res := method.Call([]reflect.Value{in})
+		req := res[0].Interface().(*request.Request)
+		req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter"))
+
+		err := req.Send()
+		for _, a := range w.Acceptors {
+			if err != nil && a.Matcher != "error" {
+				// Only matcher error is valid if there is a request error
+				continue
+			}
+
+			result := false
+			var vals []interface{}
+			switch a.Matcher {
+			case "pathAll", "path":
+				// Require all matches to be equal for result to match
+				vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
+				result = true
+				for _, val := range vals {
+					if !awsutil.DeepEqual(val, a.Expected) {
+						result = false
+						break
+					}
+				}
+			case "pathAny":
+				// Only a single match needs to equal for the result to match
+				vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
+				for _, val := range vals {
+					if awsutil.DeepEqual(val, a.Expected) {
+						result = true
+						break
+					}
+				}
+			case "status":
+				s := a.Expected.(int)
+				result = s == req.HTTPResponse.StatusCode
+			case "error":
+				if aerr, ok := err.(awserr.Error); ok {
+					result = aerr.Code() == a.Expected.(string)
+				}
+			case "pathList":
+				// ignored matcher
+			default:
+				logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s",
+					w.Config.Operation, a.Matcher)
+			}
+
+			if !result {
+				// If there was no matching result found there is nothing more to do
+				// for this response, retry the request.
+				continue
+			}
+
+			switch a.State {
+			case "success":
+				// waiter completed
+				return nil
+			case "failure":
+				// Waiter failure state triggered
+				return awserr.New("ResourceNotReady",
+					fmt.Sprintf("failed waiting for successful resource state"), err)
+			case "retry":
+				// clear the error and retry the operation
+				err = nil
+			default:
+				logf(client, "WARNING: Waiter for %s encountered unexpected state: %s",
+					w.Config.Operation, a.State)
+			}
+		}
+		if err != nil {
+			return err
+		}
+
+		time.Sleep(time.Second * time.Duration(w.Delay))
+	}
+
+	return awserr.New("ResourceNotReady",
+		fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil)
+}
+
+func logf(client reflect.Value, msg string, args ...interface{}) {
+	cfgVal := client.FieldByName("Config")
+	if !cfgVal.IsValid() {
+		return
+	}
+	if cfg, ok := cfgVal.Interface().(*aws.Config); ok && cfg.Logger != nil {
+		cfg.Logger.Log(fmt.Sprintf(msg, args...))
+	}
+}

+ 391 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/private/waiter/waiter_test.go

@@ -0,0 +1,391 @@
+package waiter_test
+
+import (
+	"bytes"
+	"io/ioutil"
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/awstesting"
+	"github.com/aws/aws-sdk-go/private/waiter"
+)
+
+type mockClient struct {
+	*client.Client
+}
+type MockInput struct{}
+type MockOutput struct {
+	States []*MockState
+}
+type MockState struct {
+	State *string
+}
+
+func (c *mockClient) MockRequest(input *MockInput) (*request.Request, *MockOutput) {
+	op := &request.Operation{
+		Name:       "Mock",
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &MockInput{}
+	}
+
+	output := &MockOutput{}
+	req := c.NewRequest(op, input, output)
+	req.Data = output
+	return req, output
+}
+
+func TestWaiterPathAll(t *testing.T) {
+	svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
+		Region: aws.String("mock-region"),
+	})}
+	svc.Handlers.Send.Clear() // mock sending
+	svc.Handlers.Unmarshal.Clear()
+	svc.Handlers.UnmarshalMeta.Clear()
+	svc.Handlers.ValidateResponse.Clear()
+
+	reqNum := 0
+	resps := []*MockOutput{
+		{ // Request 1
+			States: []*MockState{
+				{State: aws.String("pending")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 2
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 3
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("running")},
+			},
+		},
+	}
+
+	numBuiltReq := 0
+	svc.Handlers.Build.PushBack(func(r *request.Request) {
+		numBuiltReq++
+	})
+	svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		if reqNum >= len(resps) {
+			assert.Fail(t, "too many polling requests made")
+			return
+		}
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	waiterCfg := waiter.Config{
+		Operation:   "Mock",
+		Delay:       0,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "States[].State",
+				Expected: "running",
+			},
+		},
+	}
+	w := waiter.Waiter{
+		Client: svc,
+		Input:  &MockInput{},
+		Config: waiterCfg,
+	}
+
+	err := w.Wait()
+	assert.NoError(t, err)
+	assert.Equal(t, 3, numBuiltReq)
+	assert.Equal(t, 3, reqNum)
+}
+
+func TestWaiterPath(t *testing.T) {
+	svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
+		Region: aws.String("mock-region"),
+	})}
+	svc.Handlers.Send.Clear() // mock sending
+	svc.Handlers.Unmarshal.Clear()
+	svc.Handlers.UnmarshalMeta.Clear()
+	svc.Handlers.ValidateResponse.Clear()
+
+	reqNum := 0
+	resps := []*MockOutput{
+		{ // Request 1
+			States: []*MockState{
+				{State: aws.String("pending")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 2
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 3
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("running")},
+			},
+		},
+	}
+
+	numBuiltReq := 0
+	svc.Handlers.Build.PushBack(func(r *request.Request) {
+		numBuiltReq++
+	})
+	svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		if reqNum >= len(resps) {
+			assert.Fail(t, "too many polling requests made")
+			return
+		}
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	waiterCfg := waiter.Config{
+		Operation:   "Mock",
+		Delay:       0,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "path",
+				Argument: "States[].State",
+				Expected: "running",
+			},
+		},
+	}
+	w := waiter.Waiter{
+		Client: svc,
+		Input:  &MockInput{},
+		Config: waiterCfg,
+	}
+
+	err := w.Wait()
+	assert.NoError(t, err)
+	assert.Equal(t, 3, numBuiltReq)
+	assert.Equal(t, 3, reqNum)
+}
+
+func TestWaiterFailure(t *testing.T) {
+	svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
+		Region: aws.String("mock-region"),
+	})}
+	svc.Handlers.Send.Clear() // mock sending
+	svc.Handlers.Unmarshal.Clear()
+	svc.Handlers.UnmarshalMeta.Clear()
+	svc.Handlers.ValidateResponse.Clear()
+
+	reqNum := 0
+	resps := []*MockOutput{
+		{ // Request 1
+			States: []*MockState{
+				{State: aws.String("pending")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 2
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 3
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("stopping")},
+			},
+		},
+	}
+
+	numBuiltReq := 0
+	svc.Handlers.Build.PushBack(func(r *request.Request) {
+		numBuiltReq++
+	})
+	svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		if reqNum >= len(resps) {
+			assert.Fail(t, "too many polling requests made")
+			return
+		}
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	waiterCfg := waiter.Config{
+		Operation:   "Mock",
+		Delay:       0,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "States[].State",
+				Expected: "running",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "States[].State",
+				Expected: "stopping",
+			},
+		},
+	}
+	w := waiter.Waiter{
+		Client: svc,
+		Input:  &MockInput{},
+		Config: waiterCfg,
+	}
+
+	err := w.Wait().(awserr.Error)
+	assert.Error(t, err)
+	assert.Equal(t, "ResourceNotReady", err.Code())
+	assert.Equal(t, "failed waiting for successful resource state", err.Message())
+	assert.Equal(t, 3, numBuiltReq)
+	assert.Equal(t, 3, reqNum)
+}
+
+func TestWaiterError(t *testing.T) {
+	svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
+		Region: aws.String("mock-region"),
+	})}
+	svc.Handlers.Send.Clear() // mock sending
+	svc.Handlers.Unmarshal.Clear()
+	svc.Handlers.UnmarshalMeta.Clear()
+	svc.Handlers.ValidateResponse.Clear()
+
+	reqNum := 0
+	resps := []*MockOutput{
+		{ // Request 1
+			States: []*MockState{
+				{State: aws.String("pending")},
+				{State: aws.String("pending")},
+			},
+		},
+		{ // Request 2, error case
+		},
+		{ // Request 3
+			States: []*MockState{
+				{State: aws.String("running")},
+				{State: aws.String("running")},
+			},
+		},
+	}
+
+	numBuiltReq := 0
+	svc.Handlers.Build.PushBack(func(r *request.Request) {
+		numBuiltReq++
+	})
+	svc.Handlers.Send.PushBack(func(r *request.Request) {
+		if reqNum == 1 {
+			r.Error = awserr.New("MockException", "mock exception message", nil)
+			r.HTTPResponse = &http.Response{
+				StatusCode: 400,
+				Status:     http.StatusText(400),
+				Body:       ioutil.NopCloser(bytes.NewReader([]byte{})),
+			}
+			reqNum++
+		}
+	})
+	svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
+		if reqNum >= len(resps) {
+			assert.Fail(t, "too many polling requests made")
+			return
+		}
+		r.Data = resps[reqNum]
+		reqNum++
+	})
+
+	waiterCfg := waiter.Config{
+		Operation:   "Mock",
+		Delay:       0,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "States[].State",
+				Expected: "running",
+			},
+			{
+				State:    "retry",
+				Matcher:  "error",
+				Argument: "",
+				Expected: "MockException",
+			},
+		},
+	}
+	w := waiter.Waiter{
+		Client: svc,
+		Input:  &MockInput{},
+		Config: waiterCfg,
+	}
+
+	err := w.Wait()
+	assert.NoError(t, err)
+	assert.Equal(t, 3, numBuiltReq)
+	assert.Equal(t, 3, reqNum)
+}
+
+func TestWaiterStatus(t *testing.T) {
+	svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
+		Region: aws.String("mock-region"),
+	})}
+	svc.Handlers.Send.Clear() // mock sending
+	svc.Handlers.Unmarshal.Clear()
+	svc.Handlers.UnmarshalMeta.Clear()
+	svc.Handlers.ValidateResponse.Clear()
+
+	reqNum := 0
+	svc.Handlers.Build.PushBack(func(r *request.Request) {
+		reqNum++
+	})
+	svc.Handlers.Send.PushBack(func(r *request.Request) {
+		code := 200
+		if reqNum == 3 {
+			code = 404
+		}
+		r.HTTPResponse = &http.Response{
+			StatusCode: code,
+			Status:     http.StatusText(code),
+			Body:       ioutil.NopCloser(bytes.NewReader([]byte{})),
+		}
+	})
+
+	waiterCfg := waiter.Config{
+		Operation:   "Mock",
+		Delay:       0,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "status",
+				Argument: "",
+				Expected: 404,
+			},
+		},
+	}
+	w := waiter.Waiter{
+		Client: svc,
+		Input:  &MockInput{},
+		Config: waiterCfg,
+	}
+
+	err := w.Wait()
+	assert.NoError(t, err)
+	assert.Equal(t, 3, reqNum)
+}

+ 3 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/api.go

@@ -74,6 +74,7 @@ func (c *CloudWatch) DescribeAlarmHistory(input *DescribeAlarmHistoryInput) (*De
 
 func (c *CloudWatch) DescribeAlarmHistoryPages(input *DescribeAlarmHistoryInput, fn func(p *DescribeAlarmHistoryOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeAlarmHistoryRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeAlarmHistoryOutput), lastPage)
 	})
@@ -116,6 +117,7 @@ func (c *CloudWatch) DescribeAlarms(input *DescribeAlarmsInput) (*DescribeAlarms
 
 func (c *CloudWatch) DescribeAlarmsPages(input *DescribeAlarmsInput, fn func(p *DescribeAlarmsOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeAlarmsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeAlarmsOutput), lastPage)
 	})
@@ -293,6 +295,7 @@ func (c *CloudWatch) ListMetrics(input *ListMetricsInput) (*ListMetricsOutput, e
 
 func (c *CloudWatch) ListMetricsPages(input *ListMetricsInput, fn func(p *ListMetricsOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.ListMetricsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*ListMetricsOutput), lastPage)
 	})

+ 2 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go

@@ -60,3 +60,5 @@ type CloudWatchAPI interface {
 
 	SetAlarmState(*cloudwatch.SetAlarmStateInput) (*cloudwatch.SetAlarmStateOutput, error)
 }
+
+var _ CloudWatchAPI = (*cloudwatch.CloudWatch)(nil)

+ 0 - 15
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface_test.go

@@ -1,15 +0,0 @@
-// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
-
-package cloudwatchiface_test
-
-import (
-	"testing"
-
-	"github.com/aws/aws-sdk-go/service/cloudwatch"
-	"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestInterface(t *testing.T) {
-	assert.Implements(t, (*cloudwatchiface.CloudWatchAPI)(nil), cloudwatch.New(nil))
-}

+ 12 - 11
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/examples_test.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/session"
 	"github.com/aws/aws-sdk-go/service/cloudwatch"
 )
 
@@ -15,7 +16,7 @@ var _ time.Duration
 var _ bytes.Buffer
 
 func ExampleCloudWatch_DeleteAlarms() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.DeleteAlarmsInput{
 		AlarmNames: []*string{ // Required
@@ -37,7 +38,7 @@ func ExampleCloudWatch_DeleteAlarms() {
 }
 
 func ExampleCloudWatch_DescribeAlarmHistory() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.DescribeAlarmHistoryInput{
 		AlarmName:       aws.String("AlarmName"),
@@ -61,7 +62,7 @@ func ExampleCloudWatch_DescribeAlarmHistory() {
 }
 
 func ExampleCloudWatch_DescribeAlarms() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.DescribeAlarmsInput{
 		ActionPrefix:    aws.String("ActionPrefix"),
@@ -88,7 +89,7 @@ func ExampleCloudWatch_DescribeAlarms() {
 }
 
 func ExampleCloudWatch_DescribeAlarmsForMetric() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.DescribeAlarmsForMetricInput{
 		MetricName: aws.String("MetricName"), // Required
@@ -118,7 +119,7 @@ func ExampleCloudWatch_DescribeAlarmsForMetric() {
 }
 
 func ExampleCloudWatch_DisableAlarmActions() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.DisableAlarmActionsInput{
 		AlarmNames: []*string{ // Required
@@ -140,7 +141,7 @@ func ExampleCloudWatch_DisableAlarmActions() {
 }
 
 func ExampleCloudWatch_EnableAlarmActions() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.EnableAlarmActionsInput{
 		AlarmNames: []*string{ // Required
@@ -162,7 +163,7 @@ func ExampleCloudWatch_EnableAlarmActions() {
 }
 
 func ExampleCloudWatch_GetMetricStatistics() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.GetMetricStatisticsInput{
 		EndTime:    aws.Time(time.Now()),     // Required
@@ -197,7 +198,7 @@ func ExampleCloudWatch_GetMetricStatistics() {
 }
 
 func ExampleCloudWatch_ListMetrics() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.ListMetricsInput{
 		Dimensions: []*cloudwatch.DimensionFilter{
@@ -225,7 +226,7 @@ func ExampleCloudWatch_ListMetrics() {
 }
 
 func ExampleCloudWatch_PutMetricAlarm() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.PutMetricAlarmInput{
 		AlarmName:          aws.String("AlarmName"),          // Required
@@ -273,7 +274,7 @@ func ExampleCloudWatch_PutMetricAlarm() {
 }
 
 func ExampleCloudWatch_PutMetricData() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.PutMetricDataInput{
 		MetricData: []*cloudwatch.MetricDatum{ // Required
@@ -314,7 +315,7 @@ func ExampleCloudWatch_PutMetricData() {
 }
 
 func ExampleCloudWatch_SetAlarmState() {
-	svc := cloudwatch.New(nil)
+	svc := cloudwatch.New(session.New())
 
 	params := &cloudwatch.SetAlarmStateInput{
 		AlarmName:       aws.String("AlarmName"),   // Required

+ 47 - 24
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/cloudwatch/service.go

@@ -4,10 +4,9 @@ package cloudwatch
 
 import (
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
 	"github.com/aws/aws-sdk-go/private/protocol/query"
 	"github.com/aws/aws-sdk-go/private/signer/v4"
 )
@@ -52,40 +51,64 @@ import (
 // Center (http://aws.amazon.com/php/) AWS Python Developer Center (http://aws.amazon.com/python/)
 // AWS Ruby Developer Center (http://aws.amazon.com/ruby/) AWS Windows and .NET
 // Developer Center (http://aws.amazon.com/net/)
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type CloudWatch struct {
-	*service.Service
+	*client.Client
 }
 
-// Used for custom service initialization logic
-var initService func(*service.Service)
+// Used for custom client initialization logic
+var initClient func(*client.Client)
 
 // Used for custom request initialization logic
 var initRequest func(*request.Request)
 
-// New returns a new CloudWatch client.
-func New(config *aws.Config) *CloudWatch {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "monitoring",
-			APIVersion:  "2010-08-01",
-		},
+// A ServiceName is the name of the service the client will make API calls to.
+const ServiceName = "monitoring"
+
+// New creates a new instance of the CloudWatch client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a CloudWatch client from just a session.
+//     svc := cloudwatch.New(mySession)
+//
+//     // Create a CloudWatch client with additional configuration
+//     svc := cloudwatch.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *CloudWatch {
+	c := p.ClientConfig(ServiceName, cfgs...)
+	return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *CloudWatch {
+	svc := &CloudWatch{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   ServiceName,
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2010-08-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(query.Build)
-	service.Handlers.Unmarshal.PushBack(query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(query.Build)
+	svc.Handlers.Unmarshal.PushBack(query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
 
-	// Run custom service initialization if present
-	if initService != nil {
-		initService(service)
+	// Run custom client initialization if present
+	if initClient != nil {
+		initClient(svc.Client)
 	}
 
-	return &CloudWatch{service}
+	return svc
 }
 
 // newRequest creates a new request for a CloudWatch operation and runs any

+ 58 - 24
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/api.go

@@ -871,7 +871,7 @@ func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (r
 // gateway is the appliance at your end of the VPN connection. (The device on
 // the AWS side of the VPN connection is the virtual private gateway.) You must
 // provide the Internet-routable IP address of the customer gateway's external
-// interface. The IP address must be static and can't be behind a device performing
+// interface. The IP address must be static and may be behind a device performing
 // network address translation (NAT).
 //
 // For devices that use Border Gateway Protocol (BGP), you can also provide
@@ -1598,6 +1598,9 @@ func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *request.Request, o
 // of a key and optional value. Tag keys must be unique per resource.
 //
 // For more information about tags, see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html)
+// in the Amazon Elastic Compute Cloud User Guide. For more information about
+// creating IAM policies that control users' access to resources based on tags,
+// see Supported Resource-Level Permissions for Amazon EC2 API Actions (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-supported-iam-actions-resources.html)
 // in the Amazon Elastic Compute Cloud User Guide.
 func (c *EC2) CreateTags(input *CreateTagsInput) (*CreateTagsOutput, error) {
 	req, out := c.CreateTagsRequest(input)
@@ -3100,6 +3103,7 @@ func (c *EC2) DescribeInstanceStatus(input *DescribeInstanceStatusInput) (*Descr
 
 func (c *EC2) DescribeInstanceStatusPages(input *DescribeInstanceStatusInput, fn func(p *DescribeInstanceStatusOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeInstanceStatusRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeInstanceStatusOutput), lastPage)
 	})
@@ -3149,6 +3153,7 @@ func (c *EC2) DescribeInstances(input *DescribeInstancesInput) (*DescribeInstanc
 
 func (c *EC2) DescribeInstancesPages(input *DescribeInstancesInput, fn func(p *DescribeInstancesOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeInstancesRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeInstancesOutput), lastPage)
 	})
@@ -3534,6 +3539,7 @@ func (c *EC2) DescribeReservedInstancesModifications(input *DescribeReservedInst
 
 func (c *EC2) DescribeReservedInstancesModificationsPages(input *DescribeReservedInstancesModificationsInput, fn func(p *DescribeReservedInstancesModificationsOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeReservedInstancesModificationsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeReservedInstancesModificationsOutput), lastPage)
 	})
@@ -3581,6 +3587,7 @@ func (c *EC2) DescribeReservedInstancesOfferings(input *DescribeReservedInstance
 
 func (c *EC2) DescribeReservedInstancesOfferingsPages(input *DescribeReservedInstancesOfferingsInput, fn func(p *DescribeReservedInstancesOfferingsOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeReservedInstancesOfferingsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeReservedInstancesOfferingsOutput), lastPage)
 	})
@@ -3697,7 +3704,7 @@ func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *requ
 		Paginator: &request.Paginator{
 			InputTokens:     []string{"NextToken"},
 			OutputTokens:    []string{"NextToken"},
-			LimitToken:      "",
+			LimitToken:      "MaxResults",
 			TruncationToken: "",
 		},
 	}
@@ -3760,6 +3767,7 @@ func (c *EC2) DescribeSnapshots(input *DescribeSnapshotsInput) (*DescribeSnapsho
 
 func (c *EC2) DescribeSnapshotsPages(input *DescribeSnapshotsInput, fn func(p *DescribeSnapshotsOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeSnapshotsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeSnapshotsOutput), lastPage)
 	})
@@ -3961,6 +3969,7 @@ func (c *EC2) DescribeSpotPriceHistory(input *DescribeSpotPriceHistoryInput) (*D
 
 func (c *EC2) DescribeSpotPriceHistoryPages(input *DescribeSpotPriceHistoryInput, fn func(p *DescribeSpotPriceHistoryOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeSpotPriceHistoryRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeSpotPriceHistoryOutput), lastPage)
 	})
@@ -4004,6 +4013,12 @@ func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Reques
 		Name:       opDescribeTags,
 		HTTPMethod: "POST",
 		HTTPPath:   "/",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"NextToken"},
+			OutputTokens:    []string{"NextToken"},
+			LimitToken:      "MaxResults",
+			TruncationToken: "",
+		},
 	}
 
 	if input == nil {
@@ -4026,6 +4041,14 @@ func (c *EC2) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error
 	return out, err
 }
 
+func (c *EC2) DescribeTagsPages(input *DescribeTagsInput, fn func(p *DescribeTagsOutput, lastPage bool) (shouldContinue bool)) error {
+	page, _ := c.DescribeTagsRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
+	return page.EachPage(func(p interface{}, lastPage bool) bool {
+		return fn(p.(*DescribeTagsOutput), lastPage)
+	})
+}
+
 const opDescribeVolumeAttribute = "DescribeVolumeAttribute"
 
 // DescribeVolumeAttributeRequest generates a request for the DescribeVolumeAttribute operation.
@@ -4126,6 +4149,7 @@ func (c *EC2) DescribeVolumeStatus(input *DescribeVolumeStatusInput) (*DescribeV
 
 func (c *EC2) DescribeVolumeStatusPages(input *DescribeVolumeStatusInput, fn func(p *DescribeVolumeStatusOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeVolumeStatusRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeVolumeStatusOutput), lastPage)
 	})
@@ -4176,6 +4200,7 @@ func (c *EC2) DescribeVolumes(input *DescribeVolumesInput) (*DescribeVolumesOutp
 
 func (c *EC2) DescribeVolumesPages(input *DescribeVolumesInput, fn func(p *DescribeVolumesOutput, lastPage bool) (shouldContinue bool)) error {
 	page, _ := c.DescribeVolumesRequest(input)
+	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
 	return page.EachPage(func(p interface{}, lastPage bool) bool {
 		return fn(p.(*DescribeVolumesOutput), lastPage)
 	})
@@ -9206,7 +9231,8 @@ func (s CreateSpotDatafeedSubscriptionOutput) GoString() string {
 type CreateSubnetInput struct {
 	// The Availability Zone for the subnet.
 	//
-	// Default: Amazon EC2 selects one for you (recommended).
+	// Default: AWS selects one for you. If you create more than one subnet in
+	// your VPC, we may not necessarily select a different zone for each subnet.
 	AvailabilityZone *string `type:"string"`
 
 	// The network range for the subnet, in CIDR notation. For example, 10.0.0.0/24.
@@ -12262,7 +12288,7 @@ type DescribeInstancesInput struct {
 	//
 	//   network-interface.vpc-id - The ID of the VPC for the network interface.
 	//
-	//   network-interface.network-interface.id - The ID of the network interface.
+	//   network-interface.network-interface-id - The ID of the network interface.
 	//
 	//   network-interface.owner-id - The ID of the owner of the network interface.
 	//
@@ -14153,7 +14179,7 @@ type DescribeSpotInstanceRequestsInput struct {
 	//
 	//   launch.image-id - The ID of the AMI.
 	//
-	//   launch.instance-type - The type of instance (for example, m1.small).
+	//   launch.instance-type - The type of instance (for example, m3.medium).
 	//
 	//   launch.kernel-id - The kernel ID.
 	//
@@ -14291,7 +14317,7 @@ type DescribeSpotPriceHistoryInput struct {
 	//
 	//   availability-zone - The Availability Zone for which prices should be returned.
 	//
-	//   instance-type - The type of instance (for example, m1.small).
+	//   instance-type - The type of instance (for example, m3.medium).
 	//
 	//   product-description - The product description for the Spot price (Linux/UNIX
 	// | SUSE Linux | Windows | Linux/UNIX (Amazon VPC) | SUSE Linux (Amazon VPC)
@@ -17491,7 +17517,7 @@ type Instance struct {
 	// Any block device mapping entries for the instance.
 	BlockDeviceMappings []*InstanceBlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"`
 
-	// The idempotency token you provided when you launched the instance.
+	// The idempotency token you provided when you launched the instance, if applicable.
 	ClientToken *string `locationName:"clientToken" type:"string"`
 
 	// Indicates whether the instance is optimized for EBS I/O. This optimization
@@ -17504,7 +17530,7 @@ type Instance struct {
 	// The hypervisor type of the instance.
 	Hypervisor *string `locationName:"hypervisor" type:"string" enum:"HypervisorType"`
 
-	// The IAM instance profile associated with the instance.
+	// The IAM instance profile associated with the instance, if applicable.
 	IamInstanceProfile *IamInstanceProfile `locationName:"iamInstanceProfile" type:"structure"`
 
 	// The ID of the AMI used to launch the instance.
@@ -17519,7 +17545,7 @@ type Instance struct {
 	// The instance type.
 	InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"`
 
-	// The kernel associated with this instance.
+	// The kernel associated with this instance, if applicable.
 	KernelId *string `locationName:"kernelId" type:"string"`
 
 	// The name of the key pair, if this instance was launched with an associated
@@ -17535,7 +17561,7 @@ type Instance struct {
 	// [EC2-VPC] One or more network interfaces for the instance.
 	NetworkInterfaces []*InstanceNetworkInterface `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"`
 
-	// The location where the instance launched.
+	// The location where the instance launched, if applicable.
 	Placement *Placement `locationName:"placement" type:"structure"`
 
 	// The value is Windows for Windows instances; otherwise blank.
@@ -17543,23 +17569,25 @@ type Instance struct {
 
 	// The private DNS name assigned to the instance. This DNS name can only be
 	// used inside the Amazon EC2 network. This name is not available until the
-	// instance enters the running state.
+	// instance enters the running state. For EC2-VPC, this name is only available
+	// if you've enabled DNS hostnames for your VPC.
 	PrivateDnsName *string `locationName:"privateDnsName" type:"string"`
 
 	// The private IP address assigned to the instance.
 	PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"`
 
-	// The product codes attached to this instance.
+	// The product codes attached to this instance, if applicable.
 	ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"`
 
 	// The public DNS name assigned to the instance. This name is not available
-	// until the instance enters the running state.
+	// until the instance enters the running state. For EC2-VPC, this name is only
+	// available if you've enabled DNS hostnames for your VPC.
 	PublicDnsName *string `locationName:"dnsName" type:"string"`
 
-	// The public IP address assigned to the instance.
+	// The public IP address assigned to the instance, if applicable.
 	PublicIpAddress *string `locationName:"ipAddress" type:"string"`
 
-	// The RAM disk associated with this instance.
+	// The RAM disk associated with this instance, if applicable.
 	RamdiskId *string `locationName:"ramdiskId" type:"string"`
 
 	// The root device name (for example, /dev/sda1 or /dev/xvda).
@@ -17580,7 +17608,7 @@ type Instance struct {
 	// in the Amazon Virtual Private Cloud User Guide.
 	SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"`
 
-	// The ID of the Spot Instance request.
+	// If the request is a Spot instance request, the ID of the request.
 	SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"`
 
 	// Specifies whether enhanced networking is enabled.
@@ -17595,7 +17623,7 @@ type Instance struct {
 	// The reason for the most recent state transition. This might be an empty string.
 	StateTransitionReason *string `locationName:"reason" type:"string"`
 
-	// The ID of the subnet in which the instance is running.
+	// [EC2-VPC] The ID of the subnet in which the instance is running.
 	SubnetId *string `locationName:"subnetId" type:"string"`
 
 	// Any tags assigned to the instance.
@@ -17604,7 +17632,7 @@ type Instance struct {
 	// The virtualization type of the instance.
 	VirtualizationType *string `locationName:"virtualizationType" type:"string" enum:"VirtualizationType"`
 
-	// The ID of the VPC in which the instance is running.
+	// [EC2-VPC] The ID of the VPC in which the instance is running.
 	VpcId *string `locationName:"vpcId" type:"string"`
 
 	metadataInstance `json:"-" xml:"-"`
@@ -18960,7 +18988,9 @@ type ModifyVpcAttributeInput struct {
 	// Indicates whether the instances launched in the VPC get DNS hostnames. If
 	// enabled, instances in the VPC get DNS hostnames; otherwise, they do not.
 	//
-	// You can only enable DNS hostnames if you also enable DNS support.
+	// You cannot modify the DNS resolution and DNS hostnames attributes in the
+	// same request. Use separate requests for each attribute. You can only enable
+	// DNS hostnames if you've enabled DNS support.
 	EnableDnsHostnames *AttributeBooleanValue `type:"structure"`
 
 	// Indicates whether the DNS resolution is supported for the VPC. If enabled,
@@ -18968,6 +18998,9 @@ type ModifyVpcAttributeInput struct {
 	// or the reserved IP address at the base of the VPC network range "plus two"
 	// will succeed. If disabled, the Amazon provided DNS service in the VPC that
 	// resolves public DNS hostnames to IP addresses is not enabled.
+	//
+	// You cannot modify the DNS resolution and DNS hostnames attributes in the
+	// same request. Use separate requests for each attribute.
 	EnableDnsSupport *AttributeBooleanValue `type:"structure"`
 
 	// The ID of the VPC.
@@ -20589,7 +20622,7 @@ type RequestSpotInstancesInput struct {
 	// the instance a two-minute warning before it terminates.
 	//
 	// Note that you can't specify an Availability Zone group or a launch group
-	// if you specify a required duration.
+	// if you specify a duration.
 	BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"`
 
 	// Unique, case-sensitive identifier that you provide to ensure the idempotency
@@ -22348,8 +22381,8 @@ func (s SpotFleetRequestConfigData) GoString() string {
 
 // Describes a Spot instance request.
 type SpotInstanceRequest struct {
-	// If you specified a required duration and your request was fulfilled, this
-	// is the fixed hourly price in effect for the Spot instance while it runs.
+	// If you specified a duration and your Spot instance request was fulfilled,
+	// this is the fixed hourly price in effect for the Spot instance while it runs.
 	ActualBlockHourlyPrice *string `locationName:"actualBlockHourlyPrice" type:"string"`
 
 	// The Availability Zone group. If you specify the same Availability Zone group
@@ -22357,7 +22390,7 @@ type SpotInstanceRequest struct {
 	// Availability Zone.
 	AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"`
 
-	// The required duration for the Spot instance, in minutes.
+	// The duration for the Spot instance, in minutes.
 	BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"`
 
 	// The date and time when the Spot instance request was created, in UTC format
@@ -22460,7 +22493,8 @@ func (s SpotInstanceStateFault) GoString() string {
 
 // Describes the status of a Spot instance request.
 type SpotInstanceStatus struct {
-	// The status code.
+	// The status code. For a list of status codes, see Spot Bid Status Codes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html#spot-instance-bid-status-understand)
+	// in the Amazon Elastic Compute Cloud User Guide.
 	Code *string `locationName:"code" type:"string"`
 
 	// The description for the status code.

+ 18 - 20
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations.go

@@ -3,8 +3,10 @@ package ec2
 import (
 	"time"
 
+	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awsutil"
 	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/endpoints"
 )
 
 func init() {
@@ -20,38 +22,34 @@ func fillPresignedURL(r *request.Request) {
 		return
 	}
 
-	params := r.Params.(*CopySnapshotInput)
+	origParams := r.Params.(*CopySnapshotInput)
 
 	// Stop if PresignedURL/DestinationRegion is set
-	if params.PresignedUrl != nil || params.DestinationRegion != nil {
+	if origParams.PresignedUrl != nil || origParams.DestinationRegion != nil {
 		return
 	}
 
-	// First generate a copy of parameters
-	r.Params = awsutil.CopyOf(r.Params)
-	params = r.Params.(*CopySnapshotInput)
+	origParams.DestinationRegion = r.Config.Region
+	newParams := awsutil.CopyOf(r.Params).(*CopySnapshotInput)
 
-	// Set destination region. Avoids infinite handler loop.
-	// Also needed to sign sub-request.
-	params.DestinationRegion = r.Service.Config.Region
-
-	// Create a new client pointing at source region.
-	// We will use this to presign the CopySnapshot request against
-	// the source region
-	config := r.Service.Config.Copy().
+	// Create a new request based on the existing request. We will use this to
+	// presign the CopySnapshot request against the source region.
+	cfg := r.Config.Copy(aws.NewConfig().
 		WithEndpoint("").
-		WithRegion(*params.SourceRegion)
+		WithRegion(aws.StringValue(origParams.SourceRegion)))
 
-	client := New(config)
+	clientInfo := r.ClientInfo
+	clientInfo.Endpoint, clientInfo.SigningRegion = endpoints.EndpointForRegion(
+		clientInfo.ServiceName, aws.StringValue(cfg.Region), aws.BoolValue(cfg.DisableSSL))
 
 	// Presign a CopySnapshot request with modified params
-	req, _ := client.CopySnapshotRequest(params)
-	url, err := req.Presign(300 * time.Second) // 5 minutes should be enough.
-
-	if err != nil { // bubble error back up to original request
+	req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data)
+	url, err := req.Presign(5 * time.Minute) // 5 minutes should be enough.
+	if err != nil {                          // bubble error back up to original request
 		r.Error = err
+		return
 	}
 
 	// We have our URL, set it on params
-	params.PresignedUrl = &url
+	origParams.PresignedUrl = &url
 }

+ 4 - 5
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/customizations_test.go

@@ -11,10 +11,8 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-var _ = unit.Imported
-
 func TestCopySnapshotPresignedURL(t *testing.T) {
-	svc := ec2.New(&aws.Config{Region: aws.String("us-west-2")})
+	svc := ec2.New(unit.Session, &aws.Config{Region: aws.String("us-west-2")})
 
 	assert.NotPanics(t, func() {
 		// Doesn't panic on nil input
@@ -30,7 +28,8 @@ func TestCopySnapshotPresignedURL(t *testing.T) {
 
 	b, _ := ioutil.ReadAll(req.HTTPRequest.Body)
 	q, _ := url.ParseQuery(string(b))
-	url, _ := url.QueryUnescape(q.Get("PresignedUrl"))
+	u, _ := url.QueryUnescape(q.Get("PresignedUrl"))
 	assert.Equal(t, "us-west-2", q.Get("DestinationRegion"))
-	assert.Regexp(t, `^https://ec2\.us-west-1\.amazon.+&DestinationRegion=us-west-2`, url)
+	assert.Equal(t, "us-west-1", q.Get("SourceRegion"))
+	assert.Regexp(t, `^https://ec2\.us-west-1\.amazonaws\.com/.+&DestinationRegion=us-west-2`, u)
 }

+ 4 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go

@@ -486,6 +486,8 @@ type EC2API interface {
 
 	DescribeTags(*ec2.DescribeTagsInput) (*ec2.DescribeTagsOutput, error)
 
+	DescribeTagsPages(*ec2.DescribeTagsInput, func(*ec2.DescribeTagsOutput, bool) bool) error
+
 	DescribeVolumeAttributeRequest(*ec2.DescribeVolumeAttributeInput) (*request.Request, *ec2.DescribeVolumeAttributeOutput)
 
 	DescribeVolumeAttribute(*ec2.DescribeVolumeAttributeInput) (*ec2.DescribeVolumeAttributeOutput, error)
@@ -758,3 +760,5 @@ type EC2API interface {
 
 	UnmonitorInstances(*ec2.UnmonitorInstancesInput) (*ec2.UnmonitorInstancesOutput, error)
 }
+
+var _ EC2API = (*ec2.EC2)(nil)

+ 0 - 15
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface_test.go

@@ -1,15 +0,0 @@
-// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
-
-package ec2iface_test
-
-import (
-	"testing"
-
-	"github.com/aws/aws-sdk-go/service/ec2"
-	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestInterface(t *testing.T) {
-	assert.Implements(t, (*ec2iface.EC2API)(nil), ec2.New(nil))
-}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 112 - 111
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/examples_test.go


+ 47 - 24
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/service.go

@@ -4,10 +4,9 @@ package ec2
 
 import (
 	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
 	"github.com/aws/aws-sdk-go/aws/request"
-	"github.com/aws/aws-sdk-go/aws/service"
-	"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
 	"github.com/aws/aws-sdk-go/private/protocol/ec2query"
 	"github.com/aws/aws-sdk-go/private/signer/v4"
 )
@@ -16,40 +15,64 @@ import (
 // in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your
 // need to invest in hardware up front, so you can develop and deploy applications
 // faster.
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
 type EC2 struct {
-	*service.Service
+	*client.Client
 }
 
-// Used for custom service initialization logic
-var initService func(*service.Service)
+// Used for custom client initialization logic
+var initClient func(*client.Client)
 
 // Used for custom request initialization logic
 var initRequest func(*request.Request)
 
-// New returns a new EC2 client.
-func New(config *aws.Config) *EC2 {
-	service := &service.Service{
-		ServiceInfo: serviceinfo.ServiceInfo{
-			Config:      defaults.DefaultConfig.Merge(config),
-			ServiceName: "ec2",
-			APIVersion:  "2015-10-01",
-		},
+// A ServiceName is the name of the service the client will make API calls to.
+const ServiceName = "ec2"
+
+// New creates a new instance of the EC2 client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a EC2 client from just a session.
+//     svc := ec2.New(mySession)
+//
+//     // Create a EC2 client with additional configuration
+//     svc := ec2.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2 {
+	c := p.ClientConfig(ServiceName, cfgs...)
+	return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *EC2 {
+	svc := &EC2{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   ServiceName,
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2015-10-01",
+			},
+			handlers,
+		),
 	}
-	service.Initialize()
 
 	// Handlers
-	service.Handlers.Sign.PushBack(v4.Sign)
-	service.Handlers.Build.PushBack(ec2query.Build)
-	service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
-	service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
-	service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
+	svc.Handlers.Sign.PushBack(v4.Sign)
+	svc.Handlers.Build.PushBack(ec2query.Build)
+	svc.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
+	svc.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
+	svc.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
 
-	// Run custom service initialization if present
-	if initService != nil {
-		initService(service)
+	// Run custom client initialization if present
+	if initClient != nil {
+		initClient(svc.Client)
 	}
 
-	return &EC2{service}
+	return svc
 }
 
 // newRequest creates a new request for a EC2 operation and runs any

+ 761 - 0
Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/ec2/waiters.go

@@ -0,0 +1,761 @@
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
+
+package ec2
+
+import (
+	"github.com/aws/aws-sdk-go/private/waiter"
+)
+
+func (c *EC2) WaitUntilBundleTaskComplete(input *DescribeBundleTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeBundleTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "BundleTasks[].State",
+				Expected: "complete",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "BundleTasks[].State",
+				Expected: "failed",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilConversionTaskCancelled(input *DescribeConversionTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeConversionTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "ConversionTasks[].State",
+				Expected: "cancelled",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilConversionTaskCompleted(input *DescribeConversionTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeConversionTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "ConversionTasks[].State",
+				Expected: "completed",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "ConversionTasks[].State",
+				Expected: "cancelled",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "ConversionTasks[].State",
+				Expected: "cancelling",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilConversionTaskDeleted(input *DescribeConversionTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeConversionTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "ConversionTasks[].State",
+				Expected: "deleted",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilCustomerGatewayAvailable(input *DescribeCustomerGatewaysInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeCustomerGateways",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "CustomerGateways[].State",
+				Expected: "available",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "CustomerGateways[].State",
+				Expected: "deleted",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "CustomerGateways[].State",
+				Expected: "deleting",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilExportTaskCancelled(input *DescribeExportTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeExportTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "ExportTasks[].State",
+				Expected: "cancelled",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilExportTaskCompleted(input *DescribeExportTasksInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeExportTasks",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "ExportTasks[].State",
+				Expected: "completed",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilImageAvailable(input *DescribeImagesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeImages",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Images[].State",
+				Expected: "available",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Images[].State",
+				Expected: "failed",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilInstanceExists(input *DescribeInstancesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstances",
+		Delay:       5,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "status",
+				Argument: "",
+				Expected: 200,
+			},
+			{
+				State:    "retry",
+				Matcher:  "error",
+				Argument: "",
+				Expected: "InvalidInstanceIDNotFound",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilInstanceRunning(input *DescribeInstancesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstances",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "running",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "shutting-down",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "terminated",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "stopping",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilInstanceStatusOk(input *DescribeInstanceStatusInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstanceStatus",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "InstanceStatuses[].InstanceStatus.Status",
+				Expected: "ok",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilInstanceStopped(input *DescribeInstancesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstances",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "stopped",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "pending",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "terminated",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilInstanceTerminated(input *DescribeInstancesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstances",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "terminated",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "pending",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Reservations[].Instances[].State.Name",
+				Expected: "stopping",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilKeyPairExists(input *DescribeKeyPairsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeKeyPairs",
+		Delay:       5,
+		MaxAttempts: 6,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "length(KeyPairs[].KeyName) > `0`",
+				Expected: true,
+			},
+			{
+				State:    "retry",
+				Matcher:  "error",
+				Argument: "",
+				Expected: "InvalidKeyPairNotFound",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilNetworkInterfaceAvailable(input *DescribeNetworkInterfacesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeNetworkInterfaces",
+		Delay:       20,
+		MaxAttempts: 10,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "NetworkInterfaces[].Status",
+				Expected: "available",
+			},
+			{
+				State:    "failure",
+				Matcher:  "error",
+				Argument: "",
+				Expected: "InvalidNetworkInterfaceIDNotFound",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilPasswordDataAvailable(input *GetPasswordDataInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "GetPasswordData",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "path",
+				Argument: "length(PasswordData) > `0`",
+				Expected: true,
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilSnapshotCompleted(input *DescribeSnapshotsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeSnapshots",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Snapshots[].State",
+				Expected: "completed",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilSpotInstanceRequestFulfilled(input *DescribeSpotInstanceRequestsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeSpotInstanceRequests",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "SpotInstanceRequests[].Status.Code",
+				Expected: "fulfilled",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "SpotInstanceRequests[].Status.Code",
+				Expected: "schedule-expired",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "SpotInstanceRequests[].Status.Code",
+				Expected: "canceled-before-fulfillment",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "SpotInstanceRequests[].Status.Code",
+				Expected: "bad-parameters",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "SpotInstanceRequests[].Status.Code",
+				Expected: "system-error",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilSubnetAvailable(input *DescribeSubnetsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeSubnets",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Subnets[].State",
+				Expected: "available",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilSystemStatusOk(input *DescribeInstanceStatusInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeInstanceStatus",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "InstanceStatuses[].SystemStatus.Status",
+				Expected: "ok",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVolumeAvailable(input *DescribeVolumesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVolumes",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Volumes[].State",
+				Expected: "available",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Volumes[].State",
+				Expected: "deleted",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVolumeDeleted(input *DescribeVolumesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVolumes",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Volumes[].State",
+				Expected: "deleted",
+			},
+			{
+				State:    "success",
+				Matcher:  "error",
+				Argument: "",
+				Expected: "InvalidVolumeNotFound",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVolumeInUse(input *DescribeVolumesInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVolumes",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Volumes[].State",
+				Expected: "in-use",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "Volumes[].State",
+				Expected: "deleted",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVpcAvailable(input *DescribeVpcsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVpcs",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "Vpcs[].State",
+				Expected: "available",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVpnConnectionAvailable(input *DescribeVpnConnectionsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVpnConnections",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "VpnConnections[].State",
+				Expected: "available",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "VpnConnections[].State",
+				Expected: "deleting",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "VpnConnections[].State",
+				Expected: "deleted",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}
+
+func (c *EC2) WaitUntilVpnConnectionDeleted(input *DescribeVpnConnectionsInput) error {
+	waiterCfg := waiter.Config{
+		Operation:   "DescribeVpnConnections",
+		Delay:       15,
+		MaxAttempts: 40,
+		Acceptors: []waiter.WaitAcceptor{
+			{
+				State:    "success",
+				Matcher:  "pathAll",
+				Argument: "VpnConnections[].State",
+				Expected: "deleted",
+			},
+			{
+				State:    "failure",
+				Matcher:  "pathAny",
+				Argument: "VpnConnections[].State",
+				Expected: "pending",
+			},
+		},
+	}
+
+	w := waiter.Waiter{
+		Client: c,
+		Input:  input,
+		Config: waiterCfg,
+	}
+	return w.Wait()
+}

+ 4 - 0
Godeps/_workspace/src/github.com/go-ini/ini/.gitignore

@@ -0,0 +1,4 @@
+testdata/conf_out.ini
+ini.sublime-project
+ini.sublime-workspace
+testdata/conf_reflect.ini

+ 191 - 0
Godeps/_workspace/src/github.com/go-ini/ini/LICENSE

@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 560 - 0
Godeps/_workspace/src/github.com/go-ini/ini/README.md

@@ -0,0 +1,560 @@
+ini [![Build Status](https://drone.io/github.com/go-ini/ini/status.png)](https://drone.io/github.com/go-ini/ini/latest) [![](http://gocover.io/_badge/github.com/go-ini/ini)](http://gocover.io/github.com/go-ini/ini)
+===
+
+![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200)
+
+Package ini provides INI file read and write functionality in Go.
+
+[简体中文](README_ZH.md)
+
+## Feature
+
+- Load multiple data sources(`[]byte` or file) with overwrites.
+- Read with recursion values.
+- Read with parent-child sections.
+- Read with auto-increment key names.
+- Read with multiple-line values.
+- Read with tons of helper methods.
+- Read and convert values to Go types.
+- Read and **WRITE** comments of sections and keys.
+- Manipulate sections, keys and comments with ease.
+- Keep sections and keys in order as you parse and save.
+
+## Installation
+
+	go get gopkg.in/ini.v1
+
+## Getting Started
+
+### Loading from data sources
+
+A **Data Source** is either raw data in type `[]byte` or a file name with type `string` and you can load **as many as** data sources you want. Passing other types will simply return an error.
+
+```go
+cfg, err := ini.Load([]byte("raw data"), "filename")
+```
+
+Or start with an empty object:
+
+```go
+cfg := ini.Empty()
+```
+
+When you cannot decide how many data sources to load at the beginning, you still able to **Append()** them later.
+
+```go
+err := cfg.Append("other file", []byte("other raw data"))
+```
+
+### Working with sections
+
+To get a section, you would need to:
+
+```go
+section, err := cfg.GetSection("section name")
+```
+
+For a shortcut for default section, just give an empty string as name:
+
+```go
+section, err := cfg.GetSection("")
+```
+
+When you're pretty sure the section exists, following code could make your life easier:
+
+```go
+section := cfg.Section("")
+```
+
+What happens when the section somehow does not exist? Don't panic, it automatically creates and returns a new section to you.
+
+To create a new section:
+
+```go
+err := cfg.NewSection("new section")
+```
+
+To get a list of sections or section names:
+
+```go
+sections := cfg.Sections()
+names := cfg.SectionStrings()
+```
+
+### Working with keys
+
+To get a key under a section:
+
+```go
+key, err := cfg.Section("").GetKey("key name")
+```
+
+Same rule applies to key operations:
+
+```go
+key := cfg.Section("").Key("key name")
+```
+
+To create a new key:
+
+```go
+err := cfg.Section("").NewKey("name", "value")
+```
+
+To get a list of keys or key names:
+
+```go
+keys := cfg.Section("").Keys()
+names := cfg.Section("").KeyStrings()
+```
+
+To get a clone hash of keys and corresponding values:
+
+```go
+hash := cfg.GetSection("").KeysHash()
+```
+
+### Working with values
+
+To get a string value:
+
+```go
+val := cfg.Section("").Key("key name").String()
+```
+
+To validate key value on the fly:
+
+```go
+val := cfg.Section("").Key("key name").Validate(func(in string) string {
+	if len(in) == 0 {
+		return "default"
+	}
+	return in
+})
+```
+
+To get value with types:
+
+```go
+// For boolean values:
+// true when value is: 1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On
+// false when value is: 0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off
+v, err = cfg.Section("").Key("BOOL").Bool()
+v, err = cfg.Section("").Key("FLOAT64").Float64()
+v, err = cfg.Section("").Key("INT").Int()
+v, err = cfg.Section("").Key("INT64").Int64()
+v, err = cfg.Section("").Key("UINT").Uint()
+v, err = cfg.Section("").Key("UINT64").Uint64()
+v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339)
+v, err = cfg.Section("").Key("TIME").Time() // RFC3339
+
+v = cfg.Section("").Key("BOOL").MustBool()
+v = cfg.Section("").Key("FLOAT64").MustFloat64()
+v = cfg.Section("").Key("INT").MustInt()
+v = cfg.Section("").Key("INT64").MustInt64()
+v = cfg.Section("").Key("UINT").MustUint()
+v = cfg.Section("").Key("UINT64").MustUint64()
+v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
+v = cfg.Section("").Key("TIME").MustTime() // RFC3339
+
+// Methods start with Must also accept one argument for default value
+// when key not found or fail to parse value to given type.
+// Except method MustString, which you have to pass a default value.
+
+v = cfg.Section("").Key("String").MustString("default")
+v = cfg.Section("").Key("BOOL").MustBool(true)
+v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
+v = cfg.Section("").Key("INT").MustInt(10)
+v = cfg.Section("").Key("INT64").MustInt64(99)
+v = cfg.Section("").Key("UINT").MustUint(3)
+v = cfg.Section("").Key("UINT64").MustUint64(6)
+v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
+v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339
+```
+
+What if my value is three-line long?
+
+```ini
+[advance]
+ADDRESS = """404 road,
+NotFound, State, 5000
+Earth"""
+```
+
+Not a problem!
+
+```go
+cfg.Section("advance").Key("ADDRESS").String()
+
+/* --- start ---
+404 road,
+NotFound, State, 5000
+Earth
+------  end  --- */
+```
+
+That's cool, how about continuation lines?
+
+```ini
+[advance]
+two_lines = how about \
+	continuation lines?
+lots_of_lines = 1 \
+	2 \
+	3 \
+	4
+```
+
+Piece of cake!
+
+```go
+cfg.Section("advance").Key("two_lines").String() // how about continuation lines?
+cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4
+```
+
+Note that single quotes around values will be stripped:
+
+```ini
+foo = "some value" // foo: some value
+bar = 'some value' // bar: some value
+```
+
+That's all? Hmm, no.
+
+#### Helper methods of working with values
+
+To get value with given candidates:
+
+```go
+v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
+v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
+v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
+v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
+v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
+v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
+v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
+v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339
+```
+
+Default value will be presented if value of key is not in candidates you given, and default value does not need be one of candidates.
+
+To validate value in a given range:
+
+```go
+vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2)
+vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20)
+vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20)
+vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9)
+vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9)
+vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime)
+vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339
+```
+
+To auto-split value into slice:
+
+```go
+vals = cfg.Section("").Key("STRINGS").Strings(",")
+vals = cfg.Section("").Key("FLOAT64S").Float64s(",")
+vals = cfg.Section("").Key("INTS").Ints(",")
+vals = cfg.Section("").Key("INT64S").Int64s(",")
+vals = cfg.Section("").Key("UINTS").Uints(",")
+vals = cfg.Section("").Key("UINT64S").Uint64s(",")
+vals = cfg.Section("").Key("TIMES").Times(",")
+```
+
+### Save your configuration
+
+Finally, it's time to save your configuration to somewhere.
+
+A typical way to save configuration is writing it to a file:
+
+```go
+// ...
+err = cfg.SaveTo("my.ini")
+err = cfg.SaveToIndent("my.ini", "\t")
+```
+
+Another way to save is writing to a `io.Writer` interface:
+
+```go
+// ...
+cfg.WriteTo(writer)
+cfg.WriteToIndent(writer, "\t")
+```
+
+## Advanced Usage
+
+### Recursive Values
+
+For all value of keys, there is a special syntax `%(<name>)s`, where `<name>` is the key name in same section or default section, and `%(<name>)s` will be replaced by corresponding value(empty string if key not found). You can use this syntax at most 99 level of recursions.
+
+```ini
+NAME = ini
+
+[author]
+NAME = Unknwon
+GITHUB = https://github.com/%(NAME)s
+
+[package]
+FULL_NAME = github.com/go-ini/%(NAME)s
+```
+
+```go
+cfg.Section("author").Key("GITHUB").String()		// https://github.com/Unknwon
+cfg.Section("package").Key("FULL_NAME").String()	// github.com/go-ini/ini
+```
+
+### Parent-child Sections
+
+You can use `.` in section name to indicate parent-child relationship between two or more sections. If the key not found in the child section, library will try again on its parent section until there is no parent section.
+
+```ini
+NAME = ini
+VERSION = v1
+IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
+
+[package]
+CLONE_URL = https://%(IMPORT_PATH)s
+
+[package.sub]
+```
+
+```go
+cfg.Section("package.sub").Key("CLONE_URL").String()	// https://gopkg.in/ini.v1
+```
+
+### Auto-increment Key Names
+
+If key name is `-` in data source, then it would be seen as special syntax for auto-increment key name start from 1, and every section is independent on counter.
+
+```ini
+[features]
+-: Support read/write comments of keys and sections
+-: Support auto-increment of key names
+-: Support load multiple files to overwrite key values
+```
+
+```go
+cfg.Section("features").KeyStrings()	// []{"#1", "#2", "#3"}
+```
+
+### Map To Struct
+
+Want more objective way to play with INI? Cool.
+
+```ini
+Name = Unknwon
+age = 21
+Male = true
+Born = 1993-01-01T20:17:05Z
+
+[Note]
+Content = Hi is a good man!
+Cities = HangZhou, Boston
+```
+
+```go
+type Note struct {
+	Content string
+	Cities  []string
+}
+
+type Person struct {
+	Name string
+	Age  int `ini:"age"`
+	Male bool
+	Born time.Time
+	Note
+	Created time.Time `ini:"-"`
+}
+
+func main() {
+	cfg, err := ini.Load("path/to/ini")
+	// ...
+	p := new(Person)
+	err = cfg.MapTo(p)
+	// ...
+
+	// Things can be simpler.
+	err = ini.MapTo(p, "path/to/ini")
+	// ...
+
+	// Just map a section? Fine.
+	n := new(Note)
+	err = cfg.Section("Note").MapTo(n)
+	// ...
+}
+```
+
+Can I have default value for field? Absolutely.
+
+Assign it before you map to struct. It will keep the value as it is if the key is not presented or got wrong type.
+
+```go
+// ...
+p := &Person{
+	Name: "Joe",
+}
+// ...
+```
+
+It's really cool, but what's the point if you can't give me my file back from struct?
+
+### Reflect From Struct
+
+Why not?
+
+```go
+type Embeded struct {
+	Dates  []time.Time `delim:"|"`
+	Places []string
+	None   []int
+}
+
+type Author struct {
+	Name      string `ini:"NAME"`
+	Male      bool
+	Age       int
+	GPA       float64
+	NeverMind string `ini:"-"`
+	*Embeded
+}
+
+func main() {
+	a := &Author{"Unknwon", true, 21, 2.8, "",
+		&Embeded{
+			[]time.Time{time.Now(), time.Now()},
+			[]string{"HangZhou", "Boston"},
+			[]int{},
+		}}
+	cfg := ini.Empty()
+	err = ini.ReflectFrom(cfg, a)
+	// ...
+}
+```
+
+So, what do I get?
+
+```ini
+NAME = Unknwon
+Male = true
+Age = 21
+GPA = 2.8
+
+[Embeded]
+Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
+Places = HangZhou,Boston
+None =
+```
+
+#### Name Mapper
+
+To save your time and make your code cleaner, this library supports [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) between struct field and actual section and key name.
+
+There are 2 built-in name mappers:
+
+- `AllCapsUnderscore`: it converts to format `ALL_CAPS_UNDERSCORE` then match section or key.
+- `TitleUnderscore`: it converts to format `title_underscore` then match section or key.
+
+To use them:
+
+```go
+type Info struct {
+	PackageName string
+}
+
+func main() {
+	err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("packag_name=ini"))
+	// ...
+
+	cfg, err := ini.Load([]byte("PACKAGE_NAME=ini"))
+	// ...
+	info := new(Info)
+	cfg.NameMapper = ini.AllCapsUnderscore
+	err = cfg.MapTo(info)
+	// ...
+}
+```
+
+Same rules of name mapper apply to `ini.ReflectFromWithMapper` function.
+
+#### Other Notes On Map/Reflect
+
+Any embedded struct is treated as a section by default, and there is no automatic parent-child relations in map/reflect feature:
+
+```go
+type Child struct {
+	Age string
+}
+
+type Parent struct {
+	Name string
+	Child
+}
+
+type Config struct {
+	City string
+	Parent
+}
+```
+
+Example configuration:
+
+```ini
+City = Boston
+
+[Parent]
+Name = Unknwon
+
+[Child]
+Age = 21
+```
+
+What if, yes, I'm paranoid, I want embedded struct to be in the same section. Well, all roads lead to Rome.
+
+```go
+type Child struct {
+	Age string
+}
+
+type Parent struct {
+	Name string
+	Child `ini:"Parent"`
+}
+
+type Config struct {
+	City string
+	Parent
+}
+```
+
+Example configuration:
+
+```ini
+City = Boston
+
+[Parent]
+Name = Unknwon
+Age = 21
+```
+
+## Getting Help
+
+- [API Documentation](https://gowalker.org/gopkg.in/ini.v1)
+- [File An Issue](https://github.com/go-ini/ini/issues/new)
+
+## FAQs
+
+### What does `BlockMode` field do?
+
+By default, library lets you read and write values so we need a locker to make sure your data is safe. But in cases that you are very sure about only reading data through the library, you can set `cfg.BlockMode = false` to speed up read operations about **50-70%** faster.
+
+### Why another INI library?
+
+Many people are using my another INI library [goconfig](https://github.com/Unknwon/goconfig), so the reason for this one is I would like to make more Go style code. Also when you set `cfg.BlockMode = false`, this one is about **10-30%** faster.
+
+To make those changes I have to confirm API broken, so it's safer to keep it in another place and start using `gopkg.in` to version my package at this time.(PS: shorter import path)
+
+## License
+
+This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.

+ 547 - 0
Godeps/_workspace/src/github.com/go-ini/ini/README_ZH.md

@@ -0,0 +1,547 @@
+本包提供了 Go 语言中读写 INI 文件的功能。
+
+## 功能特性
+
+- 支持覆盖加载多个数据源(`[]byte` 或文件)
+- 支持递归读取键值
+- 支持读取父子分区
+- 支持读取自增键名
+- 支持读取多行的键值
+- 支持大量辅助方法
+- 支持在读取时直接转换为 Go 语言类型
+- 支持读取和 **写入** 分区和键的注释
+- 轻松操作分区、键值和注释
+- 在保存文件时分区和键值会保持原有的顺序
+
+## 下载安装
+
+    go get gopkg.in/ini.v1
+
+## 开始使用
+
+### 从数据源加载
+
+一个 **数据源** 可以是 `[]byte` 类型的原始数据,或 `string` 类型的文件路径。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。
+
+```go
+cfg, err := ini.Load([]byte("raw data"), "filename")
+```
+
+或者从一个空白的文件开始:
+
+```go
+cfg := ini.Empty()
+```
+
+当您在一开始无法决定需要加载哪些数据源时,仍可以使用 **Append()** 在需要的时候加载它们。
+
+```go
+err := cfg.Append("other file", []byte("other raw data"))
+```
+
+### 操作分区(Section)
+
+获取指定分区:
+
+```go
+section, err := cfg.GetSection("section name")
+```
+
+如果您想要获取默认分区,则可以用空字符串代替分区名:
+
+```go
+section, err := cfg.GetSection("")
+```
+
+当您非常确定某个分区是存在的,可以使用以下简便方法:
+
+```go
+section := cfg.Section("")
+```
+
+如果不小心判断错了,要获取的分区其实是不存在的,那会发生什么呢?没事的,它会自动创建并返回一个对应的分区对象给您。
+
+创建一个分区:
+
+```go
+err := cfg.NewSection("new section")
+```
+
+获取所有分区对象或名称:
+
+```go
+sections := cfg.Sections()
+names := cfg.SectionStrings()
+```
+
+### 操作键(Key)
+
+获取某个分区下的键:
+
+```go
+key, err := cfg.Section("").GetKey("key name")
+```
+
+和分区一样,您也可以直接获取键而忽略错误处理:
+
+```go
+key := cfg.Section("").Key("key name")
+```
+
+创建一个新的键:
+
+```go
+err := cfg.Section("").NewKey("name", "value")
+```
+
+获取分区下的所有键或键名:
+
+```go
+keys := cfg.Section("").Keys()
+names := cfg.Section("").KeyStrings()
+```
+
+获取分区下的所有键值对的克隆:
+
+```go
+hash := cfg.GetSection("").KeysHash()
+```
+
+### 操作键值(Value)
+
+获取一个类型为字符串(string)的值:
+
+```go
+val := cfg.Section("").Key("key name").String()
+```
+
+获取值的同时通过自定义函数进行处理验证:
+
+```go
+val := cfg.Section("").Key("key name").Validate(func(in string) string {
+	if len(in) == 0 {
+		return "default"
+	}
+	return in
+})
+```
+
+获取其它类型的值:
+
+```go
+// 布尔值的规则:
+// true 当值为:1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On
+// false 当值为:0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off
+v, err = cfg.Section("").Key("BOOL").Bool()
+v, err = cfg.Section("").Key("FLOAT64").Float64()
+v, err = cfg.Section("").Key("INT").Int()
+v, err = cfg.Section("").Key("INT64").Int64()
+v, err = cfg.Section("").Key("UINT").Uint()
+v, err = cfg.Section("").Key("UINT64").Uint64()
+v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339)
+v, err = cfg.Section("").Key("TIME").Time() // RFC3339
+
+v = cfg.Section("").Key("BOOL").MustBool()
+v = cfg.Section("").Key("FLOAT64").MustFloat64()
+v = cfg.Section("").Key("INT").MustInt()
+v = cfg.Section("").Key("INT64").MustInt64()
+v = cfg.Section("").Key("UINT").MustUint()
+v = cfg.Section("").Key("UINT64").MustUint64()
+v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
+v = cfg.Section("").Key("TIME").MustTime() // RFC3339
+
+// 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值,
+// 当键不存在或者转换失败时,则会直接返回该默认值。
+// 但是,MustString 方法必须传递一个默认值。
+
+v = cfg.Seciont("").Key("String").MustString("default")
+v = cfg.Section("").Key("BOOL").MustBool(true)
+v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
+v = cfg.Section("").Key("INT").MustInt(10)
+v = cfg.Section("").Key("INT64").MustInt64(99)
+v = cfg.Section("").Key("UINT").MustUint(3)
+v = cfg.Section("").Key("UINT64").MustUint64(6)
+v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
+v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339
+```
+
+如果我的值有好多行怎么办?
+
+```ini
+[advance]
+ADDRESS = """404 road,
+NotFound, State, 5000
+Earth"""
+```
+
+嗯哼?小 case!
+
+```go
+cfg.Section("advance").Key("ADDRESS").String()
+
+/* --- start ---
+404 road,
+NotFound, State, 5000
+Earth
+------  end  --- */
+```
+
+赞爆了!那要是我属于一行的内容写不下想要写到第二行怎么办?
+
+```ini
+[advance]
+two_lines = how about \
+	continuation lines?
+lots_of_lines = 1 \
+	2 \
+	3 \
+	4
+```
+
+简直是小菜一碟!
+
+```go
+cfg.Section("advance").Key("two_lines").String() // how about continuation lines?
+cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4
+```
+
+需要注意的是,值两侧的单引号会被自动剔除:
+
+```ini
+foo = "some value" // foo: some value
+bar = 'some value' // bar: some value
+```
+
+这就是全部了?哈哈,当然不是。
+
+#### 操作键值的辅助方法
+
+获取键值时设定候选值:
+
+```go
+v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
+v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
+v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
+v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
+v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
+v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
+v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
+v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339
+```
+
+如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。
+
+验证获取的值是否在指定范围内:
+
+```go
+vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2)
+vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20)
+vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20)
+vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9)
+vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9)
+vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime)
+vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339
+```
+
+自动分割键值为切片(slice):
+
+```go
+vals = cfg.Section("").Key("STRINGS").Strings(",")
+vals = cfg.Section("").Key("FLOAT64S").Float64s(",")
+vals = cfg.Section("").Key("INTS").Ints(",")
+vals = cfg.Section("").Key("INT64S").Int64s(",")
+vals = cfg.Section("").Key("UINTS").Uints(",")
+vals = cfg.Section("").Key("UINT64S").Uint64s(",")
+vals = cfg.Section("").Key("TIMES").Times(",")
+```
+
+### 保存配置
+
+终于到了这个时刻,是时候保存一下配置了。
+
+比较原始的做法是输出配置到某个文件:
+
+```go
+// ...
+err = cfg.SaveTo("my.ini")
+err = cfg.SaveToIndent("my.ini", "\t")
+```
+
+另一个比较高级的做法是写入到任何实现 `io.Writer` 接口的对象中:
+
+```go
+// ...
+cfg.WriteTo(writer)
+cfg.WriteToIndent(writer, "\t")
+```
+
+### 高级用法
+
+#### 递归读取键值
+
+在获取所有键值的过程中,特殊语法 `%(<name>)s` 会被应用,其中 `<name>` 可以是相同分区或者默认分区下的键名。字符串 `%(<name>)s` 会被相应的键值所替代,如果指定的键不存在,则会用空字符串替代。您可以最多使用 99 层的递归嵌套。
+
+```ini
+NAME = ini
+
+[author]
+NAME = Unknwon
+GITHUB = https://github.com/%(NAME)s
+
+[package]
+FULL_NAME = github.com/go-ini/%(NAME)s
+```
+
+```go
+cfg.Section("author").Key("GITHUB").String()		// https://github.com/Unknwon
+cfg.Section("package").Key("FULL_NAME").String()	// github.com/go-ini/ini
+```
+
+#### 读取父子分区
+
+您可以在分区名称中使用 `.` 来表示两个或多个分区之间的父子关系。如果某个键在子分区中不存在,则会去它的父分区中再次寻找,直到没有父分区为止。
+
+```ini
+NAME = ini
+VERSION = v1
+IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
+
+[package]
+CLONE_URL = https://%(IMPORT_PATH)s
+
+[package.sub]
+```
+
+```go
+cfg.Section("package.sub").Key("CLONE_URL").String()	// https://gopkg.in/ini.v1
+```
+
+#### 读取自增键名
+
+如果数据源中的键名为 `-`,则认为该键使用了自增键名的特殊语法。计数器从 1 开始,并且分区之间是相互独立的。
+
+```ini
+[features]
+-: Support read/write comments of keys and sections
+-: Support auto-increment of key names
+-: Support load multiple files to overwrite key values
+```
+
+```go
+cfg.Section("features").KeyStrings()	// []{"#1", "#2", "#3"}
+```
+
+### 映射到结构
+
+想要使用更加面向对象的方式玩转 INI 吗?好主意。
+
+```ini
+Name = Unknwon
+age = 21
+Male = true
+Born = 1993-01-01T20:17:05Z
+
+[Note]
+Content = Hi is a good man!
+Cities = HangZhou, Boston
+```
+
+```go
+type Note struct {
+	Content string
+	Cities  []string
+}
+
+type Person struct {
+	Name string
+	Age  int `ini:"age"`
+	Male bool
+	Born time.Time
+	Note
+	Created time.Time `ini:"-"`
+}
+
+func main() {
+	cfg, err := ini.Load("path/to/ini")
+	// ...
+	p := new(Person)
+	err = cfg.MapTo(p)
+	// ...
+
+	// 一切竟可以如此的简单。
+	err = ini.MapTo(p, "path/to/ini")
+	// ...
+
+	// 嗯哼?只需要映射一个分区吗?
+	n := new(Note)
+	err = cfg.Section("Note").MapTo(n)
+	// ...
+}
+```
+
+结构的字段怎么设置默认值呢?很简单,只要在映射之前对指定字段进行赋值就可以了。如果键未找到或者类型错误,该值不会发生改变。
+
+```go
+// ...
+p := &Person{
+	Name: "Joe",
+}
+// ...
+```
+
+这样玩 INI 真的好酷啊!然而,如果不能还给我原来的配置文件,有什么卵用?
+
+### 从结构反射
+
+可是,我有说不能吗?
+
+```go
+type Embeded struct {
+	Dates  []time.Time `delim:"|"`
+	Places []string
+	None   []int
+}
+
+type Author struct {
+	Name      string `ini:"NAME"`
+	Male      bool
+	Age       int
+	GPA       float64
+	NeverMind string `ini:"-"`
+	*Embeded
+}
+
+func main() {
+	a := &Author{"Unknwon", true, 21, 2.8, "",
+		&Embeded{
+			[]time.Time{time.Now(), time.Now()},
+			[]string{"HangZhou", "Boston"},
+			[]int{},
+		}}
+	cfg := ini.Empty()
+	err = ini.ReflectFrom(cfg, a)
+	// ...
+}
+```
+
+瞧瞧,奇迹发生了。
+
+```ini
+NAME = Unknwon
+Male = true
+Age = 21
+GPA = 2.8
+
+[Embeded]
+Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
+Places = HangZhou,Boston
+None =
+```
+
+#### 名称映射器(Name Mapper)
+
+为了节省您的时间并简化代码,本库支持类型为 [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) 的名称映射器,该映射器负责结构字段名与分区名和键名之间的映射。
+
+目前有 2 款内置的映射器:
+
+- `AllCapsUnderscore`:该映射器将字段名转换至格式 `ALL_CAPS_UNDERSCORE` 后再去匹配分区名和键名。
+- `TitleUnderscore`:该映射器将字段名转换至格式 `title_underscore` 后再去匹配分区名和键名。
+
+使用方法:
+
+```go
+type Info struct{
+	PackageName string
+}
+
+func main() {
+	err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("packag_name=ini"))
+	// ...
+
+	cfg, err := ini.Load([]byte("PACKAGE_NAME=ini"))
+	// ...
+	info := new(Info)
+	cfg.NameMapper = ini.AllCapsUnderscore
+	err = cfg.MapTo(info)
+	// ...
+}
+```
+
+使用函数 `ini.ReflectFromWithMapper` 时也可应用相同的规则。
+
+#### 映射/反射的其它说明
+
+任何嵌入的结构都会被默认认作一个不同的分区,并且不会自动产生所谓的父子分区关联:
+
+```go
+type Child struct {
+	Age string
+}
+
+type Parent struct {
+	Name string
+	Child
+}
+
+type Config struct {
+	City string
+	Parent
+}
+```
+
+示例配置文件:
+
+```ini
+City = Boston
+
+[Parent]
+Name = Unknwon
+
+[Child]
+Age = 21
+```
+
+很好,但是,我就是要嵌入结构也在同一个分区。好吧,你爹是李刚!
+
+```go
+type Child struct {
+	Age string
+}
+
+type Parent struct {
+	Name string
+	Child `ini:"Parent"`
+}
+
+type Config struct {
+	City string
+	Parent
+}
+```
+
+示例配置文件:
+
+```ini
+City = Boston
+
+[Parent]
+Name = Unknwon
+Age = 21
+```
+
+## 获取帮助
+
+- [API 文档](https://gowalker.org/gopkg.in/ini.v1)
+- [创建工单](https://github.com/go-ini/ini/issues/new)
+
+## 常见问题
+
+### 字段 `BlockMode` 是什么?
+
+默认情况下,本库会在您进行读写操作时采用锁机制来确保数据时间。但在某些情况下,您非常确定只进行读操作。此时,您可以通过设置 `cfg.BlockMode = false` 来将读操作提升大约 **50-70%** 的性能。
+
+### 为什么要写另一个 INI 解析库?
+
+许多人都在使用我的 [goconfig](https://github.com/Unknwon/goconfig) 来完成对 INI 文件的操作,但我希望使用更加 Go 风格的代码。并且当您设置 `cfg.BlockMode = false` 时,会有大约 **10-30%** 的性能提升。
+
+为了做出这些改变,我必须对 API 进行破坏,所以新开一个仓库是最安全的做法。除此之外,本库直接使用 `gopkg.in` 来进行版本化发布。(其实真相是导入路径更短了)

+ 1226 - 0
Godeps/_workspace/src/github.com/go-ini/ini/ini.go

@@ -0,0 +1,1226 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+// Package ini provides INI file read and write functionality in Go.
+package ini
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	DEFAULT_SECTION = "DEFAULT"
+	// Maximum allowed depth when recursively substituing variable names.
+	_DEPTH_VALUES = 99
+
+	_VERSION = "1.6.0"
+)
+
+func Version() string {
+	return _VERSION
+}
+
+var (
+	LineBreak = "\n"
+
+	// Variable regexp pattern: %(variable)s
+	varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
+
+	// Write spaces around "=" to look better.
+	PrettyFormat = true
+)
+
+func init() {
+	if runtime.GOOS == "windows" {
+		LineBreak = "\r\n"
+	}
+}
+
+func inSlice(str string, s []string) bool {
+	for _, v := range s {
+		if str == v {
+			return true
+		}
+	}
+	return false
+}
+
+// dataSource is a interface that returns file content.
+type dataSource interface {
+	ReadCloser() (io.ReadCloser, error)
+}
+
+type sourceFile struct {
+	name string
+}
+
+func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) {
+	return os.Open(s.name)
+}
+
+type bytesReadCloser struct {
+	reader io.Reader
+}
+
+func (rc *bytesReadCloser) Read(p []byte) (n int, err error) {
+	return rc.reader.Read(p)
+}
+
+func (rc *bytesReadCloser) Close() error {
+	return nil
+}
+
+type sourceData struct {
+	data []byte
+}
+
+func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
+	return &bytesReadCloser{bytes.NewReader(s.data)}, nil
+}
+
+//  ____  __.
+// |    |/ _|____ ___.__.
+// |      <_/ __ <   |  |
+// |    |  \  ___/\___  |
+// |____|__ \___  > ____|
+//         \/   \/\/
+
+// Key represents a key under a section.
+type Key struct {
+	s          *Section
+	Comment    string
+	name       string
+	value      string
+	isAutoIncr bool
+}
+
+// Name returns name of key.
+func (k *Key) Name() string {
+	return k.name
+}
+
+// Value returns raw value of key for performance purpose.
+func (k *Key) Value() string {
+	return k.value
+}
+
+// String returns string representation of value.
+func (k *Key) String() string {
+	val := k.value
+	if strings.Index(val, "%") == -1 {
+		return val
+	}
+
+	for i := 0; i < _DEPTH_VALUES; i++ {
+		vr := varPattern.FindString(val)
+		if len(vr) == 0 {
+			break
+		}
+
+		// Take off leading '%(' and trailing ')s'.
+		noption := strings.TrimLeft(vr, "%(")
+		noption = strings.TrimRight(noption, ")s")
+
+		// Search in the same section.
+		nk, err := k.s.GetKey(noption)
+		if err != nil {
+			// Search again in default section.
+			nk, _ = k.s.f.Section("").GetKey(noption)
+		}
+
+		// Substitute by new value and take off leading '%(' and trailing ')s'.
+		val = strings.Replace(val, vr, nk.value, -1)
+	}
+	return val
+}
+
+// Validate accepts a validate function which can
+// return modifed result as key value.
+func (k *Key) Validate(fn func(string) string) string {
+	return fn(k.String())
+}
+
+// parseBool returns the boolean value represented by the string.
+//
+// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On,
+// 0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off.
+// Any other value returns an error.
+func parseBool(str string) (value bool, err error) {
+	switch str {
+	case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "ON", "on", "On":
+		return true, nil
+	case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "OFF", "off", "Off":
+		return false, nil
+	}
+	return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
+}
+
+// Bool returns bool type value.
+func (k *Key) Bool() (bool, error) {
+	return parseBool(k.String())
+}
+
+// Float64 returns float64 type value.
+func (k *Key) Float64() (float64, error) {
+	return strconv.ParseFloat(k.String(), 64)
+}
+
+// Int returns int type value.
+func (k *Key) Int() (int, error) {
+	return strconv.Atoi(k.String())
+}
+
+// Int64 returns int64 type value.
+func (k *Key) Int64() (int64, error) {
+	return strconv.ParseInt(k.String(), 10, 64)
+}
+
+// Uint returns uint type valued.
+func (k *Key) Uint() (uint, error) {
+	u, e := strconv.ParseUint(k.String(), 10, 64)
+	return uint(u), e
+}
+
+// Uint64 returns uint64 type value.
+func (k *Key) Uint64() (uint64, error) {
+	return strconv.ParseUint(k.String(), 10, 64)
+}
+
+// Duration returns time.Duration type value.
+func (k *Key) Duration() (time.Duration, error) {
+	return time.ParseDuration(k.String())
+}
+
+// TimeFormat parses with given format and returns time.Time type value.
+func (k *Key) TimeFormat(format string) (time.Time, error) {
+	return time.Parse(format, k.String())
+}
+
+// Time parses with RFC3339 format and returns time.Time type value.
+func (k *Key) Time() (time.Time, error) {
+	return k.TimeFormat(time.RFC3339)
+}
+
+// MustString returns default value if key value is empty.
+func (k *Key) MustString(defaultVal string) string {
+	val := k.String()
+	if len(val) == 0 {
+		return defaultVal
+	}
+	return val
+}
+
+// MustBool always returns value without error,
+// it returns false if error occurs.
+func (k *Key) MustBool(defaultVal ...bool) bool {
+	val, err := k.Bool()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustFloat64 always returns value without error,
+// it returns 0.0 if error occurs.
+func (k *Key) MustFloat64(defaultVal ...float64) float64 {
+	val, err := k.Float64()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustInt always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustInt(defaultVal ...int) int {
+	val, err := k.Int()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustInt64 always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustInt64(defaultVal ...int64) int64 {
+	val, err := k.Int64()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustUint always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustUint(defaultVal ...uint) uint {
+	val, err := k.Uint()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustUint64 always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustUint64(defaultVal ...uint64) uint64 {
+	val, err := k.Uint64()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustDuration always returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration {
+	val, err := k.Duration()
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustTimeFormat always parses with given format and returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
+	val, err := k.TimeFormat(format)
+	if len(defaultVal) > 0 && err != nil {
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustTime always parses with RFC3339 format and returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
+	return k.MustTimeFormat(time.RFC3339, defaultVal...)
+}
+
+// In always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) In(defaultVal string, candidates []string) string {
+	val := k.String()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InFloat64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
+	val := k.MustFloat64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InInt always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InInt(defaultVal int, candidates []int) int {
+	val := k.MustInt()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InInt64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
+	val := k.MustInt64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InUint always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InUint(defaultVal uint, candidates []uint) uint {
+	val := k.MustUint()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InUint64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
+	val := k.MustUint64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InTimeFormat always parses with given format and returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
+	val := k.MustTimeFormat(format)
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InTime always parses with RFC3339 format and returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
+	return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
+}
+
+// RangeFloat64 checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 {
+	val := k.MustFloat64()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeInt checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeInt(defaultVal, min, max int) int {
+	val := k.MustInt()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeInt64 checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeInt64(defaultVal, min, max int64) int64 {
+	val := k.MustInt64()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeTimeFormat checks if value with given format is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time {
+	val := k.MustTimeFormat(format)
+	if val.Unix() < min.Unix() || val.Unix() > max.Unix() {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeTime checks if value with RFC3339 format is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time {
+	return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max)
+}
+
+// Strings returns list of string devide by given delimiter.
+func (k *Key) Strings(delim string) []string {
+	str := k.String()
+	if len(str) == 0 {
+		return []string{}
+	}
+
+	vals := strings.Split(str, delim)
+	for i := range vals {
+		vals[i] = strings.TrimSpace(vals[i])
+	}
+	return vals
+}
+
+// Float64s returns list of float64 devide by given delimiter.
+func (k *Key) Float64s(delim string) []float64 {
+	strs := k.Strings(delim)
+	vals := make([]float64, len(strs))
+	for i := range strs {
+		vals[i], _ = strconv.ParseFloat(strs[i], 64)
+	}
+	return vals
+}
+
+// Ints returns list of int devide by given delimiter.
+func (k *Key) Ints(delim string) []int {
+	strs := k.Strings(delim)
+	vals := make([]int, len(strs))
+	for i := range strs {
+		vals[i], _ = strconv.Atoi(strs[i])
+	}
+	return vals
+}
+
+// Int64s returns list of int64 devide by given delimiter.
+func (k *Key) Int64s(delim string) []int64 {
+	strs := k.Strings(delim)
+	vals := make([]int64, len(strs))
+	for i := range strs {
+		vals[i], _ = strconv.ParseInt(strs[i], 10, 64)
+	}
+	return vals
+}
+
+// Uints returns list of uint devide by given delimiter.
+func (k *Key) Uints(delim string) []uint {
+	strs := k.Strings(delim)
+	vals := make([]uint, len(strs))
+	for i := range strs {
+		u, _ := strconv.ParseUint(strs[i], 10, 64)
+		vals[i] = uint(u)
+	}
+	return vals
+}
+
+// Uint64s returns list of uint64 devide by given delimiter.
+func (k *Key) Uint64s(delim string) []uint64 {
+	strs := k.Strings(delim)
+	vals := make([]uint64, len(strs))
+	for i := range strs {
+		vals[i], _ = strconv.ParseUint(strs[i], 10, 64)
+	}
+	return vals
+}
+
+// TimesFormat parses with given format and returns list of time.Time devide by given delimiter.
+func (k *Key) TimesFormat(format, delim string) []time.Time {
+	strs := k.Strings(delim)
+	vals := make([]time.Time, len(strs))
+	for i := range strs {
+		vals[i], _ = time.Parse(format, strs[i])
+	}
+	return vals
+}
+
+// Times parses with RFC3339 format and returns list of time.Time devide by given delimiter.
+func (k *Key) Times(delim string) []time.Time {
+	return k.TimesFormat(time.RFC3339, delim)
+}
+
+// SetValue changes key value.
+func (k *Key) SetValue(v string) {
+	k.value = v
+}
+
+//   _________              __  .__
+//  /   _____/ ____   _____/  |_|__| ____   ____
+//  \_____  \_/ __ \_/ ___\   __\  |/  _ \ /    \
+//  /        \  ___/\  \___|  | |  (  <_> )   |  \
+// /_______  /\___  >\___  >__| |__|\____/|___|  /
+//         \/     \/     \/                    \/
+
+// Section represents a config section.
+type Section struct {
+	f        *File
+	Comment  string
+	name     string
+	keys     map[string]*Key
+	keyList  []string
+	keysHash map[string]string
+}
+
+func newSection(f *File, name string) *Section {
+	return &Section{f, "", name, make(map[string]*Key), make([]string, 0, 10), make(map[string]string)}
+}
+
+// Name returns name of Section.
+func (s *Section) Name() string {
+	return s.name
+}
+
+// NewKey creates a new key to given section.
+func (s *Section) NewKey(name, val string) (*Key, error) {
+	if len(name) == 0 {
+		return nil, errors.New("error creating new key: empty key name")
+	}
+
+	if s.f.BlockMode {
+		s.f.lock.Lock()
+		defer s.f.lock.Unlock()
+	}
+
+	if inSlice(name, s.keyList) {
+		s.keys[name].value = val
+		return s.keys[name], nil
+	}
+
+	s.keyList = append(s.keyList, name)
+	s.keys[name] = &Key{s, "", name, val, false}
+	s.keysHash[name] = val
+	return s.keys[name], nil
+}
+
+// GetKey returns key in section by given name.
+func (s *Section) GetKey(name string) (*Key, error) {
+	// FIXME: change to section level lock?
+	if s.f.BlockMode {
+		s.f.lock.RLock()
+	}
+	key := s.keys[name]
+	if s.f.BlockMode {
+		s.f.lock.RUnlock()
+	}
+
+	if key == nil {
+		// Check if it is a child-section.
+		sname := s.name
+		for {
+			if i := strings.LastIndex(sname, "."); i > -1 {
+				sname = sname[:i]
+				sec, err := s.f.GetSection(sname)
+				if err != nil {
+					continue
+				}
+				return sec.GetKey(name)
+			} else {
+				break
+			}
+		}
+		return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
+	}
+	return key, nil
+}
+
+// Key assumes named Key exists in section and returns a zero-value when not.
+func (s *Section) Key(name string) *Key {
+	key, err := s.GetKey(name)
+	if err != nil {
+		// It's OK here because the only possible error is empty key name,
+		// but if it's empty, this piece of code won't be executed.
+		key, _ = s.NewKey(name, "")
+		return key
+	}
+	return key
+}
+
+// Keys returns list of keys of section.
+func (s *Section) Keys() []*Key {
+	keys := make([]*Key, len(s.keyList))
+	for i := range s.keyList {
+		keys[i] = s.Key(s.keyList[i])
+	}
+	return keys
+}
+
+// KeyStrings returns list of key names of section.
+func (s *Section) KeyStrings() []string {
+	list := make([]string, len(s.keyList))
+	copy(list, s.keyList)
+	return list
+}
+
+// KeysHash returns keys hash consisting of names and values.
+func (s *Section) KeysHash() map[string]string {
+	if s.f.BlockMode {
+		s.f.lock.RLock()
+		defer s.f.lock.RUnlock()
+	}
+
+	hash := map[string]string{}
+	for key, value := range s.keysHash {
+		hash[key] = value
+	}
+	return hash
+}
+
+// DeleteKey deletes a key from section.
+func (s *Section) DeleteKey(name string) {
+	if s.f.BlockMode {
+		s.f.lock.Lock()
+		defer s.f.lock.Unlock()
+	}
+
+	for i, k := range s.keyList {
+		if k == name {
+			s.keyList = append(s.keyList[:i], s.keyList[i+1:]...)
+			delete(s.keys, name)
+			return
+		}
+	}
+}
+
+// ___________.__.__
+// \_   _____/|__|  |   ____
+//  |    __)  |  |  | _/ __ \
+//  |     \   |  |  |_\  ___/
+//  \___  /   |__|____/\___  >
+//      \/                 \/
+
+// File represents a combination of a or more INI file(s) in memory.
+type File struct {
+	// Should make things safe, but sometimes doesn't matter.
+	BlockMode bool
+	// Make sure data is safe in multiple goroutines.
+	lock sync.RWMutex
+
+	// Allow combination of multiple data sources.
+	dataSources []dataSource
+	// Actual data is stored here.
+	sections map[string]*Section
+
+	// To keep data in order.
+	sectionList []string
+
+	NameMapper
+}
+
+// newFile initializes File object with given data sources.
+func newFile(dataSources []dataSource) *File {
+	return &File{
+		BlockMode:   true,
+		dataSources: dataSources,
+		sections:    make(map[string]*Section),
+		sectionList: make([]string, 0, 10),
+	}
+}
+
+func parseDataSource(source interface{}) (dataSource, error) {
+	switch s := source.(type) {
+	case string:
+		return sourceFile{s}, nil
+	case []byte:
+		return &sourceData{s}, nil
+	default:
+		return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
+	}
+}
+
+// Load loads and parses from INI data sources.
+// Arguments can be mixed of file name with string type, or raw data in []byte.
+func Load(source interface{}, others ...interface{}) (_ *File, err error) {
+	sources := make([]dataSource, len(others)+1)
+	sources[0], err = parseDataSource(source)
+	if err != nil {
+		return nil, err
+	}
+	for i := range others {
+		sources[i+1], err = parseDataSource(others[i])
+		if err != nil {
+			return nil, err
+		}
+	}
+	f := newFile(sources)
+	return f, f.Reload()
+}
+
+// Empty returns an empty file object.
+func Empty() *File {
+	// Ignore error here, we sure our data is good.
+	f, _ := Load([]byte(""))
+	return f
+}
+
+// NewSection creates a new section.
+func (f *File) NewSection(name string) (*Section, error) {
+	if len(name) == 0 {
+		return nil, errors.New("error creating new section: empty section name")
+	}
+
+	if f.BlockMode {
+		f.lock.Lock()
+		defer f.lock.Unlock()
+	}
+
+	if inSlice(name, f.sectionList) {
+		return f.sections[name], nil
+	}
+
+	f.sectionList = append(f.sectionList, name)
+	f.sections[name] = newSection(f, name)
+	return f.sections[name], nil
+}
+
+// NewSections creates a list of sections.
+func (f *File) NewSections(names ...string) (err error) {
+	for _, name := range names {
+		if _, err = f.NewSection(name); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// GetSection returns section by given name.
+func (f *File) GetSection(name string) (*Section, error) {
+	if len(name) == 0 {
+		name = DEFAULT_SECTION
+	}
+
+	if f.BlockMode {
+		f.lock.RLock()
+		defer f.lock.RUnlock()
+	}
+
+	sec := f.sections[name]
+	if sec == nil {
+		return nil, fmt.Errorf("error when getting section: section '%s' not exists", name)
+	}
+	return sec, nil
+}
+
+// Section assumes named section exists and returns a zero-value when not.
+func (f *File) Section(name string) *Section {
+	sec, err := f.GetSection(name)
+	if err != nil {
+		// Note: It's OK here because the only possible error is empty section name,
+		// but if it's empty, this piece of code won't be executed.
+		sec, _ = f.NewSection(name)
+		return sec
+	}
+	return sec
+}
+
+// Section returns list of Section.
+func (f *File) Sections() []*Section {
+	sections := make([]*Section, len(f.sectionList))
+	for i := range f.sectionList {
+		sections[i] = f.Section(f.sectionList[i])
+	}
+	return sections
+}
+
+// SectionStrings returns list of section names.
+func (f *File) SectionStrings() []string {
+	list := make([]string, len(f.sectionList))
+	copy(list, f.sectionList)
+	return list
+}
+
+// DeleteSection deletes a section.
+func (f *File) DeleteSection(name string) {
+	if f.BlockMode {
+		f.lock.Lock()
+		defer f.lock.Unlock()
+	}
+
+	if len(name) == 0 {
+		name = DEFAULT_SECTION
+	}
+
+	for i, s := range f.sectionList {
+		if s == name {
+			f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
+			delete(f.sections, name)
+			return
+		}
+	}
+}
+
+func cutComment(str string) string {
+	i := strings.Index(str, "#")
+	if i == -1 {
+		return str
+	}
+	return str[:i]
+}
+
+func checkMultipleLines(buf *bufio.Reader, line, val, valQuote string) (string, error) {
+	isEnd := false
+	for {
+		next, err := buf.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return "", err
+			}
+			isEnd = true
+		}
+		pos := strings.LastIndex(next, valQuote)
+		if pos > -1 {
+			val += next[:pos]
+			break
+		}
+		val += next
+		if isEnd {
+			return "", fmt.Errorf("error parsing line: missing closing key quote from '%s' to '%s'", line, next)
+		}
+	}
+	return val, nil
+}
+
+func checkContinuationLines(buf *bufio.Reader, val string) (string, bool, error) {
+	isEnd := false
+	for {
+		valLen := len(val)
+		if valLen == 0 || val[valLen-1] != '\\' {
+			break
+		}
+		val = val[:valLen-1]
+
+		next, err := buf.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return "", isEnd, err
+			}
+			isEnd = true
+		}
+
+		next = strings.TrimSpace(next)
+		if len(next) == 0 {
+			break
+		}
+		val += next
+	}
+	return val, isEnd, nil
+}
+
+// parse parses data through an io.Reader.
+func (f *File) parse(reader io.Reader) error {
+	buf := bufio.NewReader(reader)
+
+	// Handle BOM-UTF8.
+	// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding
+	mask, err := buf.Peek(3)
+	if err == nil && len(mask) >= 3 && mask[0] == 239 && mask[1] == 187 && mask[2] == 191 {
+		buf.Read(mask)
+	}
+
+	count := 1
+	comments := ""
+	isEnd := false
+
+	section, err := f.NewSection(DEFAULT_SECTION)
+	if err != nil {
+		return err
+	}
+
+	for {
+		line, err := buf.ReadString('\n')
+		line = strings.TrimSpace(line)
+		length := len(line)
+
+		// Check error and ignore io.EOF just for a moment.
+		if err != nil {
+			if err != io.EOF {
+				return fmt.Errorf("error reading next line: %v", err)
+			}
+			// The last line of file could be an empty line.
+			if length == 0 {
+				break
+			}
+			isEnd = true
+		}
+
+		// Skip empty lines.
+		if length == 0 {
+			continue
+		}
+
+		switch {
+		case line[0] == '#' || line[0] == ';': // Comments.
+			if len(comments) == 0 {
+				comments = line
+			} else {
+				comments += LineBreak + line
+			}
+			continue
+		case line[0] == '[' && line[length-1] == ']': // New sction.
+			section, err = f.NewSection(strings.TrimSpace(line[1 : length-1]))
+			if err != nil {
+				return err
+			}
+
+			if len(comments) > 0 {
+				section.Comment = comments
+				comments = ""
+			}
+			// Reset counter.
+			count = 1
+			continue
+		}
+
+		// Other possibilities.
+		var (
+			i        int
+			keyQuote string
+			kname    string
+			valQuote string
+			val      string
+		)
+
+		// Key name surrounded by quotes.
+		if line[0] == '"' {
+			if length > 6 && line[0:3] == `"""` {
+				keyQuote = `"""`
+			} else {
+				keyQuote = `"`
+			}
+		} else if line[0] == '`' {
+			keyQuote = "`"
+		}
+		if len(keyQuote) > 0 {
+			qLen := len(keyQuote)
+			pos := strings.Index(line[qLen:], keyQuote)
+			if pos == -1 {
+				return fmt.Errorf("error parsing line: missing closing key quote: %s", line)
+			}
+			pos = pos + qLen
+			i = strings.IndexAny(line[pos:], "=:")
+			if i < 0 {
+				return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line)
+			} else if i == pos {
+				return fmt.Errorf("error parsing line: key is empty: %s", line)
+			}
+			i = i + pos
+			kname = line[qLen:pos] // Just keep spaces inside quotes.
+		} else {
+			i = strings.IndexAny(line, "=:")
+			if i < 0 {
+				return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line)
+			} else if i == 0 {
+				return fmt.Errorf("error parsing line: key is empty: %s", line)
+			}
+			kname = strings.TrimSpace(line[0:i])
+		}
+
+		isAutoIncr := false
+		// Auto increment.
+		if kname == "-" {
+			isAutoIncr = true
+			kname = "#" + fmt.Sprint(count)
+			count++
+		}
+
+		lineRight := strings.TrimSpace(line[i+1:])
+		lineRightLength := len(lineRight)
+		firstChar := ""
+		if lineRightLength >= 2 {
+			firstChar = lineRight[0:1]
+		}
+		if firstChar == "`" {
+			valQuote = "`"
+		} else if firstChar == `"` {
+			if lineRightLength >= 3 && lineRight[0:3] == `"""` {
+				valQuote = `"""`
+			} else {
+				valQuote = `"`
+			}
+		} else if firstChar == `'` {
+			valQuote = `'`
+		}
+
+		if len(valQuote) > 0 {
+			qLen := len(valQuote)
+			pos := strings.LastIndex(lineRight[qLen:], valQuote)
+			// For multiple-line value check.
+			if pos == -1 {
+				if valQuote == `"` || valQuote == `'` {
+					return fmt.Errorf("error parsing line: single quote does not allow multiple-line value: %s", line)
+				}
+
+				val = lineRight[qLen:] + "\n"
+				val, err = checkMultipleLines(buf, line, val, valQuote)
+				if err != nil {
+					return err
+				}
+			} else {
+				val = lineRight[qLen : pos+qLen]
+			}
+		} else {
+			val = strings.TrimSpace(cutComment(lineRight))
+			val, isEnd, err = checkContinuationLines(buf, val)
+			if err != nil {
+				return err
+			}
+		}
+
+		k, err := section.NewKey(kname, val)
+		if err != nil {
+			return err
+		}
+		k.isAutoIncr = isAutoIncr
+		if len(comments) > 0 {
+			k.Comment = comments
+			comments = ""
+		}
+
+		if isEnd {
+			break
+		}
+	}
+	return nil
+}
+
+func (f *File) reload(s dataSource) error {
+	r, err := s.ReadCloser()
+	if err != nil {
+		return err
+	}
+	defer r.Close()
+
+	return f.parse(r)
+}
+
+// Reload reloads and parses all data sources.
+func (f *File) Reload() (err error) {
+	for _, s := range f.dataSources {
+		if err = f.reload(s); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Append appends one or more data sources and reloads automatically.
+func (f *File) Append(source interface{}, others ...interface{}) error {
+	ds, err := parseDataSource(source)
+	if err != nil {
+		return err
+	}
+	f.dataSources = append(f.dataSources, ds)
+	for _, s := range others {
+		ds, err = parseDataSource(s)
+		if err != nil {
+			return err
+		}
+		f.dataSources = append(f.dataSources, ds)
+	}
+	return f.Reload()
+}
+
+// WriteToIndent writes file content into io.Writer with given value indention.
+func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
+	equalSign := "="
+	if PrettyFormat {
+		equalSign = " = "
+	}
+
+	// Use buffer to make sure target is safe until finish encoding.
+	buf := bytes.NewBuffer(nil)
+	for i, sname := range f.sectionList {
+		sec := f.Section(sname)
+		if len(sec.Comment) > 0 {
+			if sec.Comment[0] != '#' && sec.Comment[0] != ';' {
+				sec.Comment = "; " + sec.Comment
+			}
+			if _, err = buf.WriteString(sec.Comment + LineBreak); err != nil {
+				return 0, err
+			}
+		}
+
+		if i > 0 {
+			if _, err = buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
+				return 0, err
+			}
+		} else {
+			// Write nothing if default section is empty.
+			if len(sec.keyList) == 0 {
+				continue
+			}
+		}
+
+		for _, kname := range sec.keyList {
+			key := sec.Key(kname)
+			if len(key.Comment) > 0 {
+				if len(indent) > 0 && sname != DEFAULT_SECTION {
+					buf.WriteString(indent)
+				}
+				if key.Comment[0] != '#' && key.Comment[0] != ';' {
+					key.Comment = "; " + key.Comment
+				}
+				if _, err = buf.WriteString(key.Comment + LineBreak); err != nil {
+					return 0, err
+				}
+			}
+
+			if len(indent) > 0 && sname != DEFAULT_SECTION {
+				buf.WriteString(indent)
+			}
+
+			switch {
+			case key.isAutoIncr:
+				kname = "-"
+			case strings.Contains(kname, "`") || strings.Contains(kname, `"`):
+				kname = `"""` + kname + `"""`
+			case strings.Contains(kname, `=`) || strings.Contains(kname, `:`):
+				kname = "`" + kname + "`"
+			}
+
+			val := key.value
+			// In case key value contains "\n", "`" or "\"".
+			if strings.Contains(val, "\n") || strings.Contains(val, "`") || strings.Contains(val, `"`) ||
+				strings.Contains(val, "#") {
+				val = `"""` + val + `"""`
+			}
+			if _, err = buf.WriteString(kname + equalSign + val + LineBreak); err != nil {
+				return 0, err
+			}
+		}
+
+		// Put a line between sections.
+		if _, err = buf.WriteString(LineBreak); err != nil {
+			return 0, err
+		}
+	}
+
+	return buf.WriteTo(w)
+}
+
+// WriteTo writes file content into io.Writer.
+func (f *File) WriteTo(w io.Writer) (int64, error) {
+	return f.WriteToIndent(w, "")
+}
+
+// SaveToIndent writes content to file system with given value indention.
+func (f *File) SaveToIndent(filename, indent string) error {
+	// Note: Because we are truncating with os.Create,
+	// 	so it's safer to save to a temporary file location and rename afte done.
+	tmpPath := filename + "." + strconv.Itoa(time.Now().Nanosecond()) + ".tmp"
+	defer os.Remove(tmpPath)
+
+	fw, err := os.Create(tmpPath)
+	if err != nil {
+		return err
+	}
+
+	if _, err = f.WriteToIndent(fw, indent); err != nil {
+		fw.Close()
+		return err
+	}
+	fw.Close()
+
+	// Remove old file and rename the new one.
+	os.Remove(filename)
+	return os.Rename(tmpPath, filename)
+}
+
+// SaveTo writes content to file system.
+func (f *File) SaveTo(filename string) error {
+	return f.SaveToIndent(filename, "")
+}

+ 512 - 0
Godeps/_workspace/src/github.com/go-ini/ini/ini_test.go

@@ -0,0 +1,512 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func Test_Version(t *testing.T) {
+	Convey("Get version", t, func() {
+		So(Version(), ShouldEqual, _VERSION)
+	})
+}
+
+const _CONF_DATA = `
+; Package name
+NAME = ini
+; Package version
+VERSION = v1
+; Package import path
+IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
+
+# Information about package author
+# Bio can be written in multiple lines.
+[author]
+NAME = Unknwon  # Succeeding comment
+E-MAIL = fake@localhost
+GITHUB = https://github.com/%(NAME)s
+BIO = """Gopher.
+Coding addict.
+Good man.
+"""  # Succeeding comment
+
+[package]
+CLONE_URL = https://%(IMPORT_PATH)s
+
+[package.sub]
+UNUSED_KEY = should be deleted
+
+[features]
+-: Support read/write comments of keys and sections
+-: Support auto-increment of key names
+-: Support load multiple files to overwrite key values
+
+[types]
+STRING = str
+BOOL = true
+BOOL_FALSE = false
+FLOAT64 = 1.25
+INT = 10
+TIME = 2015-01-01T20:17:05Z
+DURATION = 2h45m
+UINT = 3
+
+[array]
+STRINGS = en, zh, de
+FLOAT64S = 1.1, 2.2, 3.3
+INTS = 1, 2, 3
+UINTS = 1, 2, 3
+TIMES = 2015-01-01T20:17:05Z,2015-01-01T20:17:05Z,2015-01-01T20:17:05Z
+
+[note]
+empty_lines = next line is empty\
+
+[advance]
+value with quotes = "some value"
+value quote2 again = 'some value'
+true = """"2+3=5""""
+"1+1=2" = true
+"""6+1=7""" = true
+"""` + "`" + `5+5` + "`" + `""" = 10
+""""6+6"""" = 12
+` + "`" + `7-2=4` + "`" + ` = false
+ADDRESS = ` + "`" + `404 road,
+NotFound, State, 50000` + "`" + `
+
+two_lines = how about \
+	continuation lines?
+lots_of_lines = 1 \
+	2 \
+	3 \
+	4 \
+`
+
+func Test_Load(t *testing.T) {
+	Convey("Load from data sources", t, func() {
+
+		Convey("Load with empty data", func() {
+			So(Empty(), ShouldNotBeNil)
+		})
+
+		Convey("Load with multiple data sources", func() {
+			cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini")
+			So(err, ShouldBeNil)
+			So(cfg, ShouldNotBeNil)
+		})
+	})
+
+	Convey("Bad load process", t, func() {
+
+		Convey("Load from invalid data sources", func() {
+			_, err := Load(_CONF_DATA)
+			So(err, ShouldNotBeNil)
+
+			_, err = Load("testdata/404.ini")
+			So(err, ShouldNotBeNil)
+
+			_, err = Load(1)
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(""), 1)
+			So(err, ShouldNotBeNil)
+		})
+
+		Convey("Load with empty section name", func() {
+			_, err := Load([]byte("[]"))
+			So(err, ShouldNotBeNil)
+		})
+
+		Convey("Load with bad keys", func() {
+			_, err := Load([]byte(`"""name`))
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(`"""name"""`))
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(`""=1`))
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(`=`))
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(`name`))
+			So(err, ShouldNotBeNil)
+		})
+
+		Convey("Load with bad values", func() {
+			_, err := Load([]byte(`name="""Unknwon`))
+			So(err, ShouldNotBeNil)
+
+			_, err = Load([]byte(`key = "value`))
+			So(err, ShouldNotBeNil)
+		})
+	})
+}
+
+func Test_Values(t *testing.T) {
+	Convey("Test getting and setting values", t, func() {
+		cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini")
+		So(err, ShouldBeNil)
+		So(cfg, ShouldNotBeNil)
+
+		Convey("Get values in default section", func() {
+			sec := cfg.Section("")
+			So(sec, ShouldNotBeNil)
+			So(sec.Key("NAME").Value(), ShouldEqual, "ini")
+			So(sec.Key("NAME").String(), ShouldEqual, "ini")
+			So(sec.Key("NAME").Validate(func(in string) string {
+				return in
+			}), ShouldEqual, "ini")
+			So(sec.Key("NAME").Comment, ShouldEqual, "; Package name")
+			So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "gopkg.in/ini.v1")
+		})
+
+		Convey("Get values in non-default section", func() {
+			sec := cfg.Section("author")
+			So(sec, ShouldNotBeNil)
+			So(sec.Key("NAME").String(), ShouldEqual, "Unknwon")
+			So(sec.Key("GITHUB").String(), ShouldEqual, "https://github.com/Unknwon")
+
+			sec = cfg.Section("package")
+			So(sec, ShouldNotBeNil)
+			So(sec.Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1")
+		})
+
+		Convey("Get auto-increment key names", func() {
+			keys := cfg.Section("features").Keys()
+			for i, k := range keys {
+				So(k.Name(), ShouldEqual, fmt.Sprintf("#%d", i+1))
+			}
+		})
+
+		Convey("Get overwrite value", func() {
+			So(cfg.Section("author").Key("E-MAIL").String(), ShouldEqual, "u@gogs.io")
+		})
+
+		Convey("Get sections", func() {
+			sections := cfg.Sections()
+			for i, name := range []string{DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "advance"} {
+				So(sections[i].Name(), ShouldEqual, name)
+			}
+		})
+
+		Convey("Get parent section value", func() {
+			So(cfg.Section("package.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1")
+		})
+
+		Convey("Get multiple line value", func() {
+			So(cfg.Section("author").Key("BIO").String(), ShouldEqual, "Gopher.\nCoding addict.\nGood man.\n")
+		})
+
+		Convey("Get values with type", func() {
+			sec := cfg.Section("types")
+			v1, err := sec.Key("BOOL").Bool()
+			So(err, ShouldBeNil)
+			So(v1, ShouldBeTrue)
+
+			v1, err = sec.Key("BOOL_FALSE").Bool()
+			So(err, ShouldBeNil)
+			So(v1, ShouldBeFalse)
+
+			v2, err := sec.Key("FLOAT64").Float64()
+			So(err, ShouldBeNil)
+			So(v2, ShouldEqual, 1.25)
+
+			v3, err := sec.Key("INT").Int()
+			So(err, ShouldBeNil)
+			So(v3, ShouldEqual, 10)
+
+			v4, err := sec.Key("INT").Int64()
+			So(err, ShouldBeNil)
+			So(v4, ShouldEqual, 10)
+
+			v5, err := sec.Key("UINT").Uint()
+			So(err, ShouldBeNil)
+			So(v5, ShouldEqual, 3)
+
+			v6, err := sec.Key("UINT").Uint64()
+			So(err, ShouldBeNil)
+			So(v6, ShouldEqual, 3)
+
+			t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
+			So(err, ShouldBeNil)
+			v7, err := sec.Key("TIME").Time()
+			So(err, ShouldBeNil)
+			So(v7.String(), ShouldEqual, t.String())
+
+			Convey("Must get values with type", func() {
+				So(sec.Key("STRING").MustString("404"), ShouldEqual, "str")
+				So(sec.Key("BOOL").MustBool(), ShouldBeTrue)
+				So(sec.Key("FLOAT64").MustFloat64(), ShouldEqual, 1.25)
+				So(sec.Key("INT").MustInt(), ShouldEqual, 10)
+				So(sec.Key("INT").MustInt64(), ShouldEqual, 10)
+				So(sec.Key("UINT").MustUint(), ShouldEqual, 3)
+				So(sec.Key("UINT").MustUint64(), ShouldEqual, 3)
+				So(sec.Key("TIME").MustTime().String(), ShouldEqual, t.String())
+
+				dur, err := time.ParseDuration("2h45m")
+				So(err, ShouldBeNil)
+				So(sec.Key("DURATION").MustDuration().Seconds(), ShouldEqual, dur.Seconds())
+
+				Convey("Must get values with default value", func() {
+					So(sec.Key("STRING_404").MustString("404"), ShouldEqual, "404")
+					So(sec.Key("BOOL_404").MustBool(true), ShouldBeTrue)
+					So(sec.Key("FLOAT64_404").MustFloat64(2.5), ShouldEqual, 2.5)
+					So(sec.Key("INT_404").MustInt(15), ShouldEqual, 15)
+					So(sec.Key("INT_404").MustInt64(15), ShouldEqual, 15)
+					So(sec.Key("UINT_404").MustUint(6), ShouldEqual, 6)
+					So(sec.Key("UINT_404").MustUint64(6), ShouldEqual, 6)
+
+					t, err := time.Parse(time.RFC3339, "2014-01-01T20:17:05Z")
+					So(err, ShouldBeNil)
+					So(sec.Key("TIME_404").MustTime(t).String(), ShouldEqual, t.String())
+
+					So(sec.Key("DURATION_404").MustDuration(dur).Seconds(), ShouldEqual, dur.Seconds())
+				})
+			})
+		})
+
+		Convey("Get value with candidates", func() {
+			sec := cfg.Section("types")
+			So(sec.Key("STRING").In("", []string{"str", "arr", "types"}), ShouldEqual, "str")
+			So(sec.Key("FLOAT64").InFloat64(0, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25)
+			So(sec.Key("INT").InInt(0, []int{10, 20, 30}), ShouldEqual, 10)
+			So(sec.Key("INT").InInt64(0, []int64{10, 20, 30}), ShouldEqual, 10)
+			So(sec.Key("UINT").InUint(0, []uint{3, 6, 9}), ShouldEqual, 3)
+			So(sec.Key("UINT").InUint64(0, []uint64{3, 6, 9}), ShouldEqual, 3)
+
+			zt, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z")
+			So(err, ShouldBeNil)
+			t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
+			So(err, ShouldBeNil)
+			So(sec.Key("TIME").InTime(zt, []time.Time{t, time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String())
+
+			Convey("Get value with candidates and default value", func() {
+				So(sec.Key("STRING_404").In("str", []string{"str", "arr", "types"}), ShouldEqual, "str")
+				So(sec.Key("FLOAT64_404").InFloat64(1.25, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25)
+				So(sec.Key("INT_404").InInt(10, []int{10, 20, 30}), ShouldEqual, 10)
+				So(sec.Key("INT64_404").InInt64(10, []int64{10, 20, 30}), ShouldEqual, 10)
+				So(sec.Key("UINT_404").InUint(3, []uint{3, 6, 9}), ShouldEqual, 3)
+				So(sec.Key("UINT_404").InUint64(3, []uint64{3, 6, 9}), ShouldEqual, 3)
+				So(sec.Key("TIME_404").InTime(t, []time.Time{time.Now(), time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String())
+			})
+		})
+
+		Convey("Get values in range", func() {
+			sec := cfg.Section("types")
+			So(sec.Key("FLOAT64").RangeFloat64(0, 1, 2), ShouldEqual, 1.25)
+			So(sec.Key("INT").RangeInt(0, 10, 20), ShouldEqual, 10)
+			So(sec.Key("INT").RangeInt64(0, 10, 20), ShouldEqual, 10)
+
+			minT, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z")
+			So(err, ShouldBeNil)
+			midT, err := time.Parse(time.RFC3339, "2013-01-01T01:00:00Z")
+			So(err, ShouldBeNil)
+			maxT, err := time.Parse(time.RFC3339, "9999-01-01T01:00:00Z")
+			So(err, ShouldBeNil)
+			t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
+			So(err, ShouldBeNil)
+			So(sec.Key("TIME").RangeTime(t, minT, maxT).String(), ShouldEqual, t.String())
+
+			Convey("Get value in range with default value", func() {
+				So(sec.Key("FLOAT64").RangeFloat64(5, 0, 1), ShouldEqual, 5)
+				So(sec.Key("INT").RangeInt(7, 0, 5), ShouldEqual, 7)
+				So(sec.Key("INT").RangeInt64(7, 0, 5), ShouldEqual, 7)
+				So(sec.Key("TIME").RangeTime(t, minT, midT).String(), ShouldEqual, t.String())
+			})
+		})
+
+		Convey("Get values into slice", func() {
+			sec := cfg.Section("array")
+			So(strings.Join(sec.Key("STRINGS").Strings(","), ","), ShouldEqual, "en,zh,de")
+			So(len(sec.Key("STRINGS_404").Strings(",")), ShouldEqual, 0)
+
+			vals1 := sec.Key("FLOAT64S").Float64s(",")
+			for i, v := range []float64{1.1, 2.2, 3.3} {
+				So(vals1[i], ShouldEqual, v)
+			}
+
+			vals2 := sec.Key("INTS").Ints(",")
+			for i, v := range []int{1, 2, 3} {
+				So(vals2[i], ShouldEqual, v)
+			}
+
+			vals3 := sec.Key("INTS").Int64s(",")
+			for i, v := range []int64{1, 2, 3} {
+				So(vals3[i], ShouldEqual, v)
+			}
+
+			vals4 := sec.Key("UINTS").Uints(",")
+			for i, v := range []uint{1, 2, 3} {
+				So(vals4[i], ShouldEqual, v)
+			}
+
+			vals5 := sec.Key("UINTS").Uint64s(",")
+			for i, v := range []uint64{1, 2, 3} {
+				So(vals5[i], ShouldEqual, v)
+			}
+
+			t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z")
+			So(err, ShouldBeNil)
+			vals6 := sec.Key("TIMES").Times(",")
+			for i, v := range []time.Time{t, t, t} {
+				So(vals6[i].String(), ShouldEqual, v.String())
+			}
+		})
+
+		Convey("Get key hash", func() {
+			cfg.Section("").KeysHash()
+		})
+
+		Convey("Set key value", func() {
+			k := cfg.Section("author").Key("NAME")
+			k.SetValue("无闻")
+			So(k.String(), ShouldEqual, "无闻")
+		})
+
+		Convey("Get key strings", func() {
+			So(strings.Join(cfg.Section("types").KeyStrings(), ","), ShouldEqual, "STRING,BOOL,BOOL_FALSE,FLOAT64,INT,TIME,DURATION,UINT")
+		})
+
+		Convey("Delete a key", func() {
+			cfg.Section("package.sub").DeleteKey("UNUSED_KEY")
+			_, err := cfg.Section("package.sub").GetKey("UNUSED_KEY")
+			So(err, ShouldNotBeNil)
+		})
+
+		Convey("Get section strings", func() {
+			So(strings.Join(cfg.SectionStrings(), ","), ShouldEqual, "DEFAULT,author,package,package.sub,features,types,array,note,advance")
+		})
+
+		Convey("Delete a section", func() {
+			cfg.DeleteSection("")
+			So(cfg.SectionStrings()[0], ShouldNotEqual, DEFAULT_SECTION)
+		})
+
+		Convey("Create new sections", func() {
+			cfg.NewSections("test", "test2")
+			_, err := cfg.GetSection("test")
+			So(err, ShouldBeNil)
+			_, err = cfg.GetSection("test2")
+			So(err, ShouldBeNil)
+		})
+	})
+
+	Convey("Test getting and setting bad values", t, func() {
+		cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini")
+		So(err, ShouldBeNil)
+		So(cfg, ShouldNotBeNil)
+
+		Convey("Create new key with empty name", func() {
+			k, err := cfg.Section("").NewKey("", "")
+			So(err, ShouldNotBeNil)
+			So(k, ShouldBeNil)
+		})
+
+		Convey("Create new section with empty name", func() {
+			s, err := cfg.NewSection("")
+			So(err, ShouldNotBeNil)
+			So(s, ShouldBeNil)
+		})
+
+		Convey("Create new sections with empty name", func() {
+			So(cfg.NewSections(""), ShouldNotBeNil)
+		})
+
+		Convey("Get section that not exists", func() {
+			s, err := cfg.GetSection("404")
+			So(err, ShouldNotBeNil)
+			So(s, ShouldBeNil)
+
+			s = cfg.Section("404")
+			So(s, ShouldNotBeNil)
+		})
+	})
+}
+
+func Test_File_Append(t *testing.T) {
+	Convey("Append data sources", t, func() {
+		cfg, err := Load([]byte(""))
+		So(err, ShouldBeNil)
+		So(cfg, ShouldNotBeNil)
+
+		So(cfg.Append([]byte(""), []byte("")), ShouldBeNil)
+
+		Convey("Append bad data sources", func() {
+			So(cfg.Append(1), ShouldNotBeNil)
+			So(cfg.Append([]byte(""), 1), ShouldNotBeNil)
+		})
+	})
+}
+
+func Test_File_SaveTo(t *testing.T) {
+	Convey("Save file", t, func() {
+		cfg, err := Load([]byte(_CONF_DATA), "testdata/conf.ini")
+		So(err, ShouldBeNil)
+		So(cfg, ShouldNotBeNil)
+
+		cfg.Section("").Key("NAME").Comment = "Package name"
+		cfg.Section("author").Comment = `Information about package author
+# Bio can be written in multiple lines.`
+		cfg.Section("advanced").Key("val w/ pound").SetValue("my#password")
+		So(cfg.SaveTo("testdata/conf_out.ini"), ShouldBeNil)
+
+		cfg.Section("author").Key("NAME").Comment = "This is author name"
+		So(cfg.SaveToIndent("testdata/conf_out.ini", "\t"), ShouldBeNil)
+	})
+}
+
+func Benchmark_Key_Value(b *testing.B) {
+	c, _ := Load([]byte(_CONF_DATA))
+	for i := 0; i < b.N; i++ {
+		c.Section("").Key("NAME").Value()
+	}
+}
+
+func Benchmark_Key_String(b *testing.B) {
+	c, _ := Load([]byte(_CONF_DATA))
+	for i := 0; i < b.N; i++ {
+		c.Section("").Key("NAME").String()
+	}
+}
+
+func Benchmark_Key_Value_NonBlock(b *testing.B) {
+	c, _ := Load([]byte(_CONF_DATA))
+	c.BlockMode = false
+	for i := 0; i < b.N; i++ {
+		c.Section("").Key("NAME").Value()
+	}
+}
+
+func Benchmark_Key_String_NonBlock(b *testing.B) {
+	c, _ := Load([]byte(_CONF_DATA))
+	c.BlockMode = false
+	for i := 0; i < b.N; i++ {
+		c.Section("").Key("NAME").String()
+	}
+}
+
+func Benchmark_Key_SetValue(b *testing.B) {
+	c, _ := Load([]byte(_CONF_DATA))
+	for i := 0; i < b.N; i++ {
+		c.Section("").Key("NAME").SetValue("10")
+	}
+}

+ 350 - 0
Godeps/_workspace/src/github.com/go-ini/ini/struct.go

@@ -0,0 +1,350 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"reflect"
+	"time"
+	"unicode"
+)
+
+// NameMapper represents a ini tag name mapper.
+type NameMapper func(string) string
+
+// Built-in name getters.
+var (
+	// AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
+	AllCapsUnderscore NameMapper = func(raw string) string {
+		newstr := make([]rune, 0, len(raw))
+		for i, chr := range raw {
+			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
+				if i > 0 {
+					newstr = append(newstr, '_')
+				}
+			}
+			newstr = append(newstr, unicode.ToUpper(chr))
+		}
+		return string(newstr)
+	}
+	// TitleUnderscore converts to format title_underscore.
+	TitleUnderscore NameMapper = func(raw string) string {
+		newstr := make([]rune, 0, len(raw))
+		for i, chr := range raw {
+			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
+				if i > 0 {
+					newstr = append(newstr, '_')
+				}
+				chr -= ('A' - 'a')
+			}
+			newstr = append(newstr, chr)
+		}
+		return string(newstr)
+	}
+)
+
+func (s *Section) parseFieldName(raw, actual string) string {
+	if len(actual) > 0 {
+		return actual
+	}
+	if s.f.NameMapper != nil {
+		return s.f.NameMapper(raw)
+	}
+	return raw
+}
+
+func parseDelim(actual string) string {
+	if len(actual) > 0 {
+		return actual
+	}
+	return ","
+}
+
+var reflectTime = reflect.TypeOf(time.Now()).Kind()
+
+// setWithProperType sets proper value to field based on its type,
+// but it does not return error for failing parsing,
+// because we want to use default value that is already assigned to strcut.
+func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
+	switch t.Kind() {
+	case reflect.String:
+		if len(key.String()) == 0 {
+			return nil
+		}
+		field.SetString(key.String())
+	case reflect.Bool:
+		boolVal, err := key.Bool()
+		if err != nil {
+			return nil
+		}
+		field.SetBool(boolVal)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		durationVal, err := key.Duration()
+		if err == nil {
+			field.Set(reflect.ValueOf(durationVal))
+			return nil
+		}
+
+		intVal, err := key.Int64()
+		if err != nil {
+			return nil
+		}
+		field.SetInt(intVal)
+	//	byte is an alias for uint8, so supporting uint8 breaks support for byte
+	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		durationVal, err := key.Duration()
+		if err == nil {
+			field.Set(reflect.ValueOf(durationVal))
+			return nil
+		}
+
+		uintVal, err := key.Uint64()
+		if err != nil {
+			return nil
+		}
+		field.SetUint(uintVal)
+
+	case reflect.Float64:
+		floatVal, err := key.Float64()
+		if err != nil {
+			return nil
+		}
+		field.SetFloat(floatVal)
+	case reflectTime:
+		timeVal, err := key.Time()
+		if err != nil {
+			return nil
+		}
+		field.Set(reflect.ValueOf(timeVal))
+	case reflect.Slice:
+		vals := key.Strings(delim)
+		numVals := len(vals)
+		if numVals == 0 {
+			return nil
+		}
+
+		sliceOf := field.Type().Elem().Kind()
+
+		var times []time.Time
+		if sliceOf == reflectTime {
+			times = key.Times(delim)
+		}
+
+		slice := reflect.MakeSlice(field.Type(), numVals, numVals)
+		for i := 0; i < numVals; i++ {
+			switch sliceOf {
+			case reflectTime:
+				slice.Index(i).Set(reflect.ValueOf(times[i]))
+			default:
+				slice.Index(i).Set(reflect.ValueOf(vals[i]))
+			}
+		}
+		field.Set(slice)
+	default:
+		return fmt.Errorf("unsupported type '%s'", t)
+	}
+	return nil
+}
+
+func (s *Section) mapTo(val reflect.Value) error {
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+	typ := val.Type()
+
+	for i := 0; i < typ.NumField(); i++ {
+		field := val.Field(i)
+		tpField := typ.Field(i)
+
+		tag := tpField.Tag.Get("ini")
+		if tag == "-" {
+			continue
+		}
+
+		fieldName := s.parseFieldName(tpField.Name, tag)
+		if len(fieldName) == 0 || !field.CanSet() {
+			continue
+		}
+
+		isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
+		isStruct := tpField.Type.Kind() == reflect.Struct
+		if isAnonymous {
+			field.Set(reflect.New(tpField.Type.Elem()))
+		}
+
+		if isAnonymous || isStruct {
+			if sec, err := s.f.GetSection(fieldName); err == nil {
+				if err = sec.mapTo(field); err != nil {
+					return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
+				}
+				continue
+			}
+		}
+
+		if key, err := s.GetKey(fieldName); err == nil {
+			if err = setWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
+				return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
+			}
+		}
+	}
+	return nil
+}
+
+// MapTo maps section to given struct.
+func (s *Section) MapTo(v interface{}) error {
+	typ := reflect.TypeOf(v)
+	val := reflect.ValueOf(v)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+		val = val.Elem()
+	} else {
+		return errors.New("cannot map to non-pointer struct")
+	}
+
+	return s.mapTo(val)
+}
+
+// MapTo maps file to given struct.
+func (f *File) MapTo(v interface{}) error {
+	return f.Section("").MapTo(v)
+}
+
+// MapTo maps data sources to given struct with name mapper.
+func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
+	cfg, err := Load(source, others...)
+	if err != nil {
+		return err
+	}
+	cfg.NameMapper = mapper
+	return cfg.MapTo(v)
+}
+
+// MapTo maps data sources to given struct.
+func MapTo(v, source interface{}, others ...interface{}) error {
+	return MapToWithMapper(v, nil, source, others...)
+}
+
+// reflectWithProperType does the opposite thing with setWithProperType.
+func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
+	switch t.Kind() {
+	case reflect.String:
+		key.SetValue(field.String())
+	case reflect.Bool,
+		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+		reflect.Float64,
+		reflectTime:
+		key.SetValue(fmt.Sprint(field))
+	case reflect.Slice:
+		vals := field.Slice(0, field.Len())
+		if field.Len() == 0 {
+			return nil
+		}
+
+		var buf bytes.Buffer
+		isTime := fmt.Sprint(field.Type()) == "[]time.Time"
+		for i := 0; i < field.Len(); i++ {
+			if isTime {
+				buf.WriteString(vals.Index(i).Interface().(time.Time).Format(time.RFC3339))
+			} else {
+				buf.WriteString(fmt.Sprint(vals.Index(i)))
+			}
+			buf.WriteString(delim)
+		}
+		key.SetValue(buf.String()[:buf.Len()-1])
+	default:
+		return fmt.Errorf("unsupported type '%s'", t)
+	}
+	return nil
+}
+
+func (s *Section) reflectFrom(val reflect.Value) error {
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+	typ := val.Type()
+
+	for i := 0; i < typ.NumField(); i++ {
+		field := val.Field(i)
+		tpField := typ.Field(i)
+
+		tag := tpField.Tag.Get("ini")
+		if tag == "-" {
+			continue
+		}
+
+		fieldName := s.parseFieldName(tpField.Name, tag)
+		if len(fieldName) == 0 || !field.CanSet() {
+			continue
+		}
+
+		if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
+			(tpField.Type.Kind() == reflect.Struct) {
+			// Note: The only error here is section doesn't exist.
+			sec, err := s.f.GetSection(fieldName)
+			if err != nil {
+				// Note: fieldName can never be empty here, ignore error.
+				sec, _ = s.f.NewSection(fieldName)
+			}
+			if err = sec.reflectFrom(field); err != nil {
+				return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
+			}
+			continue
+		}
+
+		// Note: Same reason as secion.
+		key, err := s.GetKey(fieldName)
+		if err != nil {
+			key, _ = s.NewKey(fieldName, "")
+		}
+		if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
+			return fmt.Errorf("error reflecting field(%s): %v", fieldName, err)
+		}
+
+	}
+	return nil
+}
+
+// ReflectFrom reflects secion from given struct.
+func (s *Section) ReflectFrom(v interface{}) error {
+	typ := reflect.TypeOf(v)
+	val := reflect.ValueOf(v)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+		val = val.Elem()
+	} else {
+		return errors.New("cannot reflect from non-pointer struct")
+	}
+
+	return s.reflectFrom(val)
+}
+
+// ReflectFrom reflects file from given struct.
+func (f *File) ReflectFrom(v interface{}) error {
+	return f.Section("").ReflectFrom(v)
+}
+
+// ReflectFrom reflects data sources from given struct with name mapper.
+func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
+	cfg.NameMapper = mapper
+	return cfg.ReflectFrom(v)
+}
+
+// ReflectFrom reflects data sources from given struct.
+func ReflectFrom(cfg *File, v interface{}) error {
+	return ReflectFromWithMapper(cfg, v, nil)
+}

+ 239 - 0
Godeps/_workspace/src/github.com/go-ini/ini/struct_test.go

@@ -0,0 +1,239 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"strings"
+	"testing"
+	"time"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+type testNested struct {
+	Cities []string `delim:"|"`
+	Visits []time.Time
+	Note   string
+	Unused int `ini:"-"`
+}
+
+type testEmbeded struct {
+	GPA float64
+}
+
+type testStruct struct {
+	Name         string `ini:"NAME"`
+	Age          int
+	Male         bool
+	Money        float64
+	Born         time.Time
+	Time         time.Duration `ini:"Duration"`
+	Others       testNested
+	*testEmbeded `ini:"grade"`
+	Unused       int `ini:"-"`
+	Unsigned     uint
+}
+
+const _CONF_DATA_STRUCT = `
+NAME = Unknwon
+Age = 21
+Male = true
+Money = 1.25
+Born = 1993-10-07T20:17:05Z
+Duration = 2h45m
+Unsigned = 3
+
+[Others]
+Cities = HangZhou|Boston
+Visits = 1993-10-07T20:17:05Z, 1993-10-07T20:17:05Z
+Note = Hello world!
+
+[grade]
+GPA = 2.8
+
+[foo.bar]
+Here = there
+When = then
+`
+
+type unsupport struct {
+	Byte byte
+}
+
+type unsupport2 struct {
+	Others struct {
+		Cities byte
+	}
+}
+
+type unsupport3 struct {
+	Cities byte
+}
+
+type unsupport4 struct {
+	*unsupport3 `ini:"Others"`
+}
+
+type defaultValue struct {
+	Name   string
+	Age    int
+	Male   bool
+	Money  float64
+	Born   time.Time
+	Cities []string
+}
+
+type fooBar struct {
+	Here, When string
+}
+
+const _INVALID_DATA_CONF_STRUCT = `
+Name = 
+Age = age
+Male = 123
+Money = money
+Born = nil
+Cities = 
+`
+
+func Test_Struct(t *testing.T) {
+	Convey("Map to struct", t, func() {
+		Convey("Map file to struct", func() {
+			ts := new(testStruct)
+			So(MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil)
+
+			So(ts.Name, ShouldEqual, "Unknwon")
+			So(ts.Age, ShouldEqual, 21)
+			So(ts.Male, ShouldBeTrue)
+			So(ts.Money, ShouldEqual, 1.25)
+			So(ts.Unsigned, ShouldEqual, 3)
+
+			t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z")
+			So(err, ShouldBeNil)
+			So(ts.Born.String(), ShouldEqual, t.String())
+
+			dur, err := time.ParseDuration("2h45m")
+			So(err, ShouldBeNil)
+			So(ts.Time.Seconds(), ShouldEqual, dur.Seconds())
+
+			So(strings.Join(ts.Others.Cities, ","), ShouldEqual, "HangZhou,Boston")
+			So(ts.Others.Visits[0].String(), ShouldEqual, t.String())
+			So(ts.Others.Note, ShouldEqual, "Hello world!")
+			So(ts.testEmbeded.GPA, ShouldEqual, 2.8)
+		})
+
+		Convey("Map section to struct", func() {
+			foobar := new(fooBar)
+			f, err := Load([]byte(_CONF_DATA_STRUCT))
+			So(err, ShouldBeNil)
+
+			So(f.Section("foo.bar").MapTo(foobar), ShouldBeNil)
+			So(foobar.Here, ShouldEqual, "there")
+			So(foobar.When, ShouldEqual, "then")
+		})
+
+		Convey("Map to non-pointer struct", func() {
+			cfg, err := Load([]byte(_CONF_DATA_STRUCT))
+			So(err, ShouldBeNil)
+			So(cfg, ShouldNotBeNil)
+
+			So(cfg.MapTo(testStruct{}), ShouldNotBeNil)
+		})
+
+		Convey("Map to unsupported type", func() {
+			cfg, err := Load([]byte(_CONF_DATA_STRUCT))
+			So(err, ShouldBeNil)
+			So(cfg, ShouldNotBeNil)
+
+			cfg.NameMapper = func(raw string) string {
+				if raw == "Byte" {
+					return "NAME"
+				}
+				return raw
+			}
+			So(cfg.MapTo(&unsupport{}), ShouldNotBeNil)
+			So(cfg.MapTo(&unsupport2{}), ShouldNotBeNil)
+			So(cfg.MapTo(&unsupport4{}), ShouldNotBeNil)
+		})
+
+		Convey("Map from invalid data source", func() {
+			So(MapTo(&testStruct{}, "hi"), ShouldNotBeNil)
+		})
+
+		Convey("Map to wrong types and gain default values", func() {
+			cfg, err := Load([]byte(_INVALID_DATA_CONF_STRUCT))
+			So(err, ShouldBeNil)
+
+			t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z")
+			So(err, ShouldBeNil)
+			dv := &defaultValue{"Joe", 10, true, 1.25, t, []string{"HangZhou", "Boston"}}
+			So(cfg.MapTo(dv), ShouldBeNil)
+			So(dv.Name, ShouldEqual, "Joe")
+			So(dv.Age, ShouldEqual, 10)
+			So(dv.Male, ShouldBeTrue)
+			So(dv.Money, ShouldEqual, 1.25)
+			So(dv.Born.String(), ShouldEqual, t.String())
+			So(strings.Join(dv.Cities, ","), ShouldEqual, "HangZhou,Boston")
+		})
+	})
+
+	Convey("Reflect from struct", t, func() {
+		type Embeded struct {
+			Dates  []time.Time `delim:"|"`
+			Places []string
+			None   []int
+		}
+		type Author struct {
+			Name      string `ini:"NAME"`
+			Male      bool
+			Age       int
+			GPA       float64
+			NeverMind string `ini:"-"`
+			*Embeded  `ini:"infos"`
+		}
+		a := &Author{"Unknwon", true, 21, 2.8, "",
+			&Embeded{
+				[]time.Time{time.Now(), time.Now()},
+				[]string{"HangZhou", "Boston"},
+				[]int{},
+			}}
+		cfg := Empty()
+		So(ReflectFrom(cfg, a), ShouldBeNil)
+		cfg.SaveTo("testdata/conf_reflect.ini")
+
+		Convey("Reflect from non-point struct", func() {
+			So(ReflectFrom(cfg, Author{}), ShouldNotBeNil)
+		})
+	})
+}
+
+type testMapper struct {
+	PackageName string
+}
+
+func Test_NameGetter(t *testing.T) {
+	Convey("Test name mappers", t, func() {
+		So(MapToWithMapper(&testMapper{}, TitleUnderscore, []byte("packag_name=ini")), ShouldBeNil)
+
+		cfg, err := Load([]byte("PACKAGE_NAME=ini"))
+		So(err, ShouldBeNil)
+		So(cfg, ShouldNotBeNil)
+
+		cfg.NameMapper = AllCapsUnderscore
+		tg := new(testMapper)
+		So(cfg.MapTo(tg), ShouldBeNil)
+		So(tg.PackageName, ShouldEqual, "ini")
+	})
+}

+ 2 - 0
Godeps/_workspace/src/github.com/go-ini/ini/testdata/conf.ini

@@ -0,0 +1,2 @@
+[author]
+E-MAIL = u@gogs.io

+ 4 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/.gitignore

@@ -0,0 +1,4 @@
+jpgo
+jmespath-fuzz.zip
+cpu.out
+go-jmespath.test

+ 9 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/.travis.yml

@@ -0,0 +1,9 @@
+language: go
+
+sudo: false
+
+go:
+  - 1.4
+
+install: go get -v -t ./...
+script: make test

+ 13 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/LICENSE

@@ -0,0 +1,13 @@
+Copyright 2015 James Saryerwinnie
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

+ 44 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/Makefile

@@ -0,0 +1,44 @@
+
+CMD = jpgo
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  test                    to run all the tests"
+	@echo "  build                   to build the library and jp executable"
+	@echo "  generate                to run codegen"
+
+
+generate:
+	go generate ./...
+
+build:
+	rm -f $(CMD)
+	go build ./...
+	rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./...
+	mv cmd/$(CMD)/$(CMD) .
+
+test:
+	go test -v ./...
+
+check:
+	go vet ./...
+	@echo "golint ./..."
+	@lint=`golint ./...`; \
+	lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \
+	echo "$$lint"; \
+	if [ "$$lint" != "" ]; then exit 1; fi
+
+htmlc:
+	go test -coverprofile="/tmp/jpcov"  && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov
+
+buildfuzz:
+	go-fuzz-build github.com/jmespath/go-jmespath/fuzz
+
+fuzz: buildfuzz
+	go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/corpus
+
+bench:
+	go test -bench . -cpuprofile cpu.out
+
+pprof-cpu:
+	go tool pprof ./go-jmespath.test ./cpu.out

+ 7 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/README.md

@@ -0,0 +1,7 @@
+# go-jmespath - A JMESPath implementation in Go
+
+[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath)
+
+
+
+See http://jmespath.org for more info.

+ 12 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/api.go

@@ -0,0 +1,12 @@
+package jmespath
+
+// Search evaluates a JMESPath expression against input data and returns the result.
+func Search(expression string, data interface{}) (interface{}, error) {
+	intr := newInterpreter()
+	parser := NewParser()
+	ast, err := parser.Parse(expression)
+	if err != nil {
+		return nil, err
+	}
+	return intr.Execute(ast, data)
+}

+ 16 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/astnodetype_string.go

@@ -0,0 +1,16 @@
+// generated by stringer -type astNodeType; DO NOT EDIT
+
+package jmespath
+
+import "fmt"
+
+const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection"
+
+var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307}
+
+func (i astNodeType) String() string {
+	if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) {
+		return fmt.Sprintf("astNodeType(%d)", i)
+	}
+	return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]]
+}

+ 96 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/basic.json

@@ -0,0 +1,96 @@
+[{
+    "given":
+        {"foo": {"bar": {"baz": "correct"}}},
+     "cases": [
+         {
+            "expression": "foo",
+            "result": {"bar": {"baz": "correct"}}
+         },
+         {
+            "expression": "foo.bar",
+            "result": {"baz": "correct"}
+         },
+         {
+            "expression": "foo.bar.baz",
+            "result": "correct"
+         },
+         {
+            "expression": "foo\n.\nbar\n.baz",
+            "result": "correct"
+         },
+         {
+            "expression": "foo.bar.baz.bad",
+            "result": null
+         },
+         {
+            "expression": "foo.bar.bad",
+            "result": null
+         },
+         {
+            "expression": "foo.bad",
+            "result": null
+         },
+         {
+            "expression": "bad",
+            "result": null
+         },
+         {
+            "expression": "bad.morebad.morebad",
+            "result": null
+         }
+     ]
+},
+{
+    "given":
+        {"foo": {"bar": ["one", "two", "three"]}},
+    "cases": [
+         {
+            "expression": "foo",
+            "result": {"bar": ["one", "two", "three"]}
+         },
+         {
+            "expression": "foo.bar",
+            "result": ["one", "two", "three"]
+         }
+    ]
+},
+{
+    "given": ["one", "two", "three"],
+    "cases": [
+        {
+            "expression": "one",
+            "result": null
+        },
+        {
+            "expression": "two",
+            "result": null
+        },
+        {
+            "expression": "three",
+            "result": null
+        },
+        {
+            "expression": "one.two",
+            "result": null
+        }
+    ]
+},
+{
+    "given":
+        {"foo": {"1": ["one", "two", "three"], "-1": "bar"}},
+    "cases": [
+         {
+            "expression": "foo.\"1\"",
+            "result": ["one", "two", "three"]
+         },
+         {
+            "expression": "foo.\"1\"[0]",
+            "result": "one"
+         },
+         {
+            "expression": "foo.\"-1\"",
+            "result": "bar"
+         }
+    ]
+}
+]

+ 257 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/boolean.json

@@ -0,0 +1,257 @@
+[
+  {
+    "given": {
+      "outer": {
+        "foo": "foo",
+        "bar": "bar",
+        "baz": "baz"
+      }
+    },
+    "cases": [
+      {
+        "expression": "outer.foo || outer.bar",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.foo||outer.bar",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.bar || outer.baz",
+        "result": "bar"
+      },
+      {
+        "expression": "outer.bar||outer.baz",
+        "result": "bar"
+      },
+      {
+        "expression": "outer.bad || outer.foo",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.bad||outer.foo",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.foo || outer.bad",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.foo||outer.bad",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.bad || outer.alsobad",
+        "result": null
+      },
+      {
+        "expression": "outer.bad||outer.alsobad",
+        "result": null
+      }
+    ]
+  },
+  {
+    "given": {
+      "outer": {
+        "foo": "foo",
+        "bool": false,
+        "empty_list": [],
+        "empty_string": ""
+      }
+    },
+    "cases": [
+      {
+        "expression": "outer.empty_string || outer.foo",
+        "result": "foo"
+      },
+      {
+        "expression": "outer.nokey || outer.bool || outer.empty_list || outer.empty_string || outer.foo",
+        "result": "foo"
+      }
+    ]
+  },
+  {
+    "given": {
+      "True": true,
+      "False": false,
+      "Number": 5,
+      "EmptyList": [],
+      "Zero": 0
+    },
+    "cases": [
+      {
+        "expression": "True && False",
+        "result": false
+      },
+      {
+        "expression": "False && True",
+        "result": false
+      },
+      {
+        "expression": "True && True",
+        "result": true
+      },
+      {
+        "expression": "False && False",
+        "result": false
+      },
+      {
+        "expression": "True && Number",
+        "result": 5
+      },
+      {
+        "expression": "Number && True",
+        "result": true
+      },
+      {
+        "expression": "Number && False",
+        "result": false
+      },
+      {
+        "expression": "Number && EmptyList",
+        "result": []
+      },
+      {
+        "expression": "Number && True",
+        "result": true
+      },
+      {
+        "expression": "EmptyList && True",
+        "result": []
+      },
+      {
+        "expression": "EmptyList && False",
+        "result": []
+      },
+      {
+        "expression": "True || False",
+        "result": true
+      },
+      {
+        "expression": "True || True",
+        "result": true
+      },
+      {
+        "expression": "False || True",
+        "result": true
+      },
+      {
+        "expression": "False || False",
+        "result": false
+      },
+      {
+        "expression": "Number || EmptyList",
+        "result": 5
+      },
+      {
+        "expression": "Number || True",
+        "result": 5
+      },
+      {
+        "expression": "Number || True && False",
+        "result": 5
+      },
+      {
+        "expression": "(Number || True) && False",
+        "result": false
+      },
+      {
+        "expression": "Number || (True && False)",
+        "result": 5
+      },
+      {
+        "expression": "!True",
+        "result": false
+      },
+      {
+        "expression": "!False",
+        "result": true
+      },
+      {
+        "expression": "!Number",
+        "result": false
+      },
+      {
+        "expression": "!EmptyList",
+        "result": true
+      },
+      {
+        "expression": "True && !False",
+        "result": true
+      },
+      {
+        "expression": "True && !EmptyList",
+        "result": true
+      },
+      {
+        "expression": "!False && !EmptyList",
+        "result": true
+      },
+      {
+        "expression": "!(True && False)",
+        "result": true
+      },
+      {
+        "expression": "!Zero",
+        "result": false
+      },
+      {
+        "expression": "!!Zero",
+        "result": true
+      }
+    ]
+  },
+  {
+    "given": {
+      "one": 1,
+      "two": 2,
+      "three": 3
+    },
+    "cases": [
+      {
+        "expression": "one < two",
+        "result": true
+      },
+      {
+        "expression": "one <= two",
+        "result": true
+      },
+      {
+        "expression": "one == one",
+        "result": true
+      },
+      {
+        "expression": "one == two",
+        "result": false
+      },
+      {
+        "expression": "one > two",
+        "result": false
+      },
+      {
+        "expression": "one >= two",
+        "result": false
+      },
+      {
+        "expression": "one != two",
+        "result": true
+      },
+      {
+        "expression": "one < two && three > one",
+        "result": true
+      },
+      {
+        "expression": "one < two || three > one",
+        "result": true
+      },
+      {
+        "expression": "one < two || three < one",
+        "result": true
+      },
+      {
+        "expression": "two < one || three < one",
+        "result": false
+      }
+    ]
+  }
+]

+ 25 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/current.json

@@ -0,0 +1,25 @@
+[
+    {
+        "given": {
+            "foo": [{"name": "a"}, {"name": "b"}],
+            "bar": {"baz": "qux"}
+        },
+        "cases": [
+            {
+                "expression": "@",
+                "result": {
+                    "foo": [{"name": "a"}, {"name": "b"}],
+                    "bar": {"baz": "qux"}
+                }
+            },
+            {
+                "expression": "@.bar",
+                "result": {"baz": "qux"}
+            },
+            {
+                "expression": "@.foo[0]",
+                "result": {"name": "a"}
+            }
+        ]
+    }
+]

+ 46 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/escape.json

@@ -0,0 +1,46 @@
+[{
+    "given": {
+        "foo.bar": "dot",
+        "foo bar": "space",
+        "foo\nbar": "newline",
+        "foo\"bar": "doublequote",
+        "c:\\\\windows\\path": "windows",
+        "/unix/path": "unix",
+        "\"\"\"": "threequotes",
+        "bar": {"baz": "qux"}
+     },
+     "cases": [
+         {
+            "expression": "\"foo.bar\"",
+            "result": "dot"
+         },
+         {
+            "expression": "\"foo bar\"",
+            "result": "space"
+         },
+         {
+            "expression": "\"foo\\nbar\"",
+            "result": "newline"
+         },
+         {
+            "expression": "\"foo\\\"bar\"",
+            "result": "doublequote"
+         },
+         {
+            "expression": "\"c:\\\\\\\\windows\\\\path\"",
+            "result": "windows"
+         },
+         {
+            "expression": "\"/unix/path\"",
+            "result": "unix"
+         },
+         {
+            "expression": "\"\\\"\\\"\\\"\"",
+            "result": "threequotes"
+         },
+         {
+            "expression": "\"bar\".\"baz\"",
+            "result": "qux"
+         }
+     ]
+}]

+ 468 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/filters.json

@@ -0,0 +1,468 @@
+[
+  {
+    "given": {"foo": [{"name": "a"}, {"name": "b"}]},
+    "cases": [
+      {
+        "comment": "Matching a literal",
+        "expression": "foo[?name == 'a']",
+        "result": [{"name": "a"}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [0, 1], "bar": [2, 3]},
+    "cases": [
+      {
+        "comment": "Matching a literal",
+        "expression": "*[?[0] == `0`]",
+        "result": [[], []]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"first": "foo", "last": "bar"},
+      {"first": "foo", "last": "foo"},
+      {"first": "foo", "last": "baz"}]},
+    "cases": [
+      {
+        "comment": "Matching an expression",
+        "expression": "foo[?first == last]",
+        "result": [{"first": "foo", "last": "foo"}]
+      },
+      {
+        "comment": "Verify projection created from filter",
+        "expression": "foo[?first == last].first",
+        "result": ["foo"]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"age": 20},
+      {"age": 25},
+      {"age": 30}]},
+    "cases": [
+      {
+        "comment": "Greater than with a number",
+        "expression": "foo[?age > `25`]",
+        "result": [{"age": 30}]
+      },
+      {
+        "expression": "foo[?age >= `25`]",
+        "result": [{"age": 25}, {"age": 30}]
+      },
+      {
+        "comment": "Greater than with a number",
+        "expression": "foo[?age > `30`]",
+        "result": []
+      },
+      {
+        "comment": "Greater than with a number",
+        "expression": "foo[?age < `25`]",
+        "result": [{"age": 20}]
+      },
+      {
+        "comment": "Greater than with a number",
+        "expression": "foo[?age <= `25`]",
+        "result": [{"age": 20}, {"age": 25}]
+      },
+      {
+        "comment": "Greater than with a number",
+        "expression": "foo[?age < `20`]",
+        "result": []
+      },
+      {
+        "expression": "foo[?age == `20`]",
+        "result": [{"age": 20}]
+      },
+      {
+        "expression": "foo[?age != `20`]",
+        "result": [{"age": 25}, {"age": 30}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"top": {"name": "a"}},
+      {"top": {"name": "b"}}]},
+    "cases": [
+      {
+        "comment": "Filter with subexpression",
+        "expression": "foo[?top.name == 'a']",
+        "result": [{"top": {"name": "a"}}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"top": {"first": "foo", "last": "bar"}},
+      {"top": {"first": "foo", "last": "foo"}},
+      {"top": {"first": "foo", "last": "baz"}}]},
+    "cases": [
+      {
+        "comment": "Matching an expression",
+        "expression": "foo[?top.first == top.last]",
+        "result": [{"top": {"first": "foo", "last": "foo"}}]
+      },
+      {
+        "comment": "Matching a JSON array",
+        "expression": "foo[?top == `{\"first\": \"foo\", \"last\": \"bar\"}`]",
+        "result": [{"top": {"first": "foo", "last": "bar"}}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [
+      {"key": true},
+      {"key": false},
+      {"key": 0},
+      {"key": 1},
+      {"key": [0]},
+      {"key": {"bar": [0]}},
+      {"key": null},
+      {"key": [1]},
+      {"key": {"a":2}}
+    ]},
+    "cases": [
+      {
+        "expression": "foo[?key == `true`]",
+        "result": [{"key": true}]
+      },
+      {
+        "expression": "foo[?key == `false`]",
+        "result": [{"key": false}]
+      },
+      {
+        "expression": "foo[?key == `0`]",
+        "result": [{"key": 0}]
+      },
+      {
+        "expression": "foo[?key == `1`]",
+        "result": [{"key": 1}]
+      },
+      {
+        "expression": "foo[?key == `[0]`]",
+        "result": [{"key": [0]}]
+      },
+      {
+        "expression": "foo[?key == `{\"bar\": [0]}`]",
+        "result": [{"key": {"bar": [0]}}]
+      },
+      {
+        "expression": "foo[?key == `null`]",
+        "result": [{"key": null}]
+      },
+      {
+        "expression": "foo[?key == `[1]`]",
+        "result": [{"key": [1]}]
+      },
+      {
+        "expression": "foo[?key == `{\"a\":2}`]",
+        "result": [{"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`true` == key]",
+        "result": [{"key": true}]
+      },
+      {
+        "expression": "foo[?`false` == key]",
+        "result": [{"key": false}]
+      },
+      {
+        "expression": "foo[?`0` == key]",
+        "result": [{"key": 0}]
+      },
+      {
+        "expression": "foo[?`1` == key]",
+        "result": [{"key": 1}]
+      },
+      {
+        "expression": "foo[?`[0]` == key]",
+        "result": [{"key": [0]}]
+      },
+      {
+        "expression": "foo[?`{\"bar\": [0]}` == key]",
+        "result": [{"key": {"bar": [0]}}]
+      },
+      {
+        "expression": "foo[?`null` == key]",
+        "result": [{"key": null}]
+      },
+      {
+        "expression": "foo[?`[1]` == key]",
+        "result": [{"key": [1]}]
+      },
+      {
+        "expression": "foo[?`{\"a\":2}` == key]",
+        "result": [{"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `true`]",
+        "result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `false`]",
+        "result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `0`]",
+        "result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `1`]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `null`]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `[1]`]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?key != `{\"a\":2}`]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}]
+      },
+      {
+        "expression": "foo[?`true` != key]",
+        "result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`false` != key]",
+        "result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`0` != key]",
+        "result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`1` != key]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`null` != key]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`[1]` != key]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}]
+      },
+      {
+        "expression": "foo[?`{\"a\":2}` != key]",
+        "result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
+          {"key": {"bar": [0]}}, {"key": null}, {"key": [1]}]
+      }
+    ]
+  },
+  {
+    "given": {"reservations": [
+      {"instances": [
+        {"foo": 1, "bar": 2}, {"foo": 1, "bar": 3},
+        {"foo": 1, "bar": 2}, {"foo": 2, "bar": 1}]}]},
+    "cases": [
+      {
+        "expression": "reservations[].instances[?bar==`1`]",
+        "result": [[{"foo": 2, "bar": 1}]]
+      },
+      {
+        "expression": "reservations[*].instances[?bar==`1`]",
+        "result": [[{"foo": 2, "bar": 1}]]
+      },
+      {
+        "expression": "reservations[].instances[?bar==`1`][]",
+        "result": [{"foo": 2, "bar": 1}]
+      }
+    ]
+  },
+  {
+    "given": {
+      "baz": "other",
+      "foo": [
+        {"bar": 1}, {"bar": 2}, {"bar": 3}, {"bar": 4}, {"bar": 1, "baz": 2}
+      ]
+    },
+    "cases": [
+      {
+        "expression": "foo[?bar==`1`].bar[0]",
+        "result": []
+      }
+    ]
+  },
+  {
+    "given": {
+      "foo": [
+        {"a": 1, "b": {"c": "x"}},
+	{"a": 1, "b": {"c": "y"}},
+	{"a": 1, "b": {"c": "z"}},
+	{"a": 2, "b": {"c": "z"}},
+	{"a": 1, "baz": 2}
+      ]
+    },
+    "cases": [
+      {
+        "expression": "foo[?a==`1`].b.c",
+        "result": ["x", "y", "z"]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"name": "a"}, {"name": "b"}, {"name": "c"}]},
+    "cases": [
+      {
+        "comment": "Filter with or expression",
+        "expression": "foo[?name == 'a' || name == 'b']",
+        "result": [{"name": "a"}, {"name": "b"}]
+      },
+      {
+        "expression": "foo[?name == 'a' || name == 'e']",
+        "result": [{"name": "a"}]
+      },
+      {
+        "expression": "foo[?name == 'a' || name == 'b' || name == 'c']",
+        "result": [{"name": "a"}, {"name": "b"}, {"name": "c"}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]},
+    "cases": [
+      {
+        "comment": "Filter with and expression",
+        "expression": "foo[?a == `1` && b == `2`]",
+        "result": [{"a": 1, "b": 2}]
+      },
+      {
+        "expression": "foo[?a == `1` && b == `4`]",
+        "result": []
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]},
+    "cases": [
+      {
+        "comment": "Filter with Or and And expressions",
+        "expression": "foo[?c == `3` || a == `1` && b == `4`]",
+        "result": [{"a": 1, "b": 2, "c": 3}]
+      },
+      {
+        "expression": "foo[?b == `2` || a == `3` && b == `4`]",
+        "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
+      },
+      {
+        "expression": "foo[?a == `3` && b == `4` || b == `2`]",
+        "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
+      },
+      {
+        "expression": "foo[?(a == `3` && b == `4`) || b == `2`]",
+        "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
+      },
+      {
+        "expression": "foo[?((a == `3` && b == `4`)) || b == `2`]",
+        "result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
+      },
+      {
+        "expression": "foo[?a == `3` && (b == `4` || b == `2`)]",
+        "result": [{"a": 3, "b": 4}]
+      },
+      {
+        "expression": "foo[?a == `3` && ((b == `4` || b == `2`))]",
+        "result": [{"a": 3, "b": 4}]
+      }
+    ]
+  },
+  {
+    "given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]},
+    "cases": [
+      {
+        "comment": "Verify precedence of or/and expressions",
+        "expression": "foo[?a == `1` || b ==`2` && c == `5`]",
+        "result": [{"a": 1, "b": 2, "c": 3}]
+      },
+      {
+        "comment": "Parentheses can alter precedence",
+        "expression": "foo[?(a == `1` || b ==`2`) && c == `5`]",
+        "result": []
+      },
+      {
+        "comment": "Not expressions combined with and/or",
+        "expression": "foo[?!(a == `1` || b ==`2`)]",
+        "result": [{"a": 3, "b": 4}]
+      }
+    ]
+  },
+  {
+    "given": {
+      "foo": [
+        {"key": true},
+        {"key": false},
+        {"key": []},
+        {"key": {}},
+        {"key": [0]},
+        {"key": {"a": "b"}},
+        {"key": 0},
+        {"key": 1},
+        {"key": null},
+        {"notkey": true}
+      ]
+    },
+    "cases": [
+      {
+        "comment": "Unary filter expression",
+        "expression": "foo[?key]",
+        "result": [
+          {"key": true}, {"key": [0]}, {"key": {"a": "b"}},
+          {"key": 0}, {"key": 1}
+        ]
+      },
+      {
+        "comment": "Unary not filter expression",
+        "expression": "foo[?!key]",
+        "result": [
+          {"key": false}, {"key": []}, {"key": {}},
+          {"key": null}, {"notkey": true}
+        ]
+      },
+      {
+        "comment": "Equality with null RHS",
+        "expression": "foo[?key == `null`]",
+        "result": [
+          {"key": null}, {"notkey": true}
+        ]
+      }
+    ]
+  },
+  {
+    "given": {
+      "foo": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+    },
+    "cases": [
+      {
+        "comment": "Using @ in a filter expression",
+        "expression": "foo[?@ < `5`]",
+        "result": [0, 1, 2, 3, 4]
+      },
+      {
+        "comment": "Using @ in a filter expression",
+        "expression": "foo[?`5` > @]",
+        "result": [0, 1, 2, 3, 4]
+      },
+      {
+        "comment": "Using @ in a filter expression",
+        "expression": "foo[?@ == @]",
+        "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+      }
+    ]
+  }
+]

+ 825 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/functions.json

@@ -0,0 +1,825 @@
+[{
+  "given":
+  {
+    "foo": -1,
+    "zero": 0,
+    "numbers": [-1, 3, 4, 5],
+    "array": [-1, 3, 4, 5, "a", "100"],
+    "strings": ["a", "b", "c"],
+    "decimals": [1.01, 1.2, -1.5],
+    "str": "Str",
+    "false": false,
+    "empty_list": [],
+    "empty_hash": {},
+    "objects": {"foo": "bar", "bar": "baz"},
+    "null_key": null
+  },
+  "cases": [
+    {
+      "expression": "abs(foo)",
+      "result": 1
+    },
+    {
+      "expression": "abs(foo)",
+      "result": 1
+    },
+    {
+      "expression": "abs(str)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "abs(array[1])",
+      "result": 3
+    },
+    {
+      "expression": "abs(array[1])",
+      "result": 3
+    },
+    {
+      "expression": "abs(`false`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "abs(`-24`)",
+      "result": 24
+    },
+    {
+      "expression": "abs(`-24`)",
+      "result": 24
+    },
+    {
+      "expression": "abs(`1`, `2`)",
+      "error": "invalid-arity"
+    },
+    {
+      "expression": "abs()",
+      "error": "invalid-arity"
+    },
+    {
+      "expression": "unknown_function(`1`, `2`)",
+      "error": "unknown-function"
+    },
+    {
+      "expression": "avg(numbers)",
+      "result": 2.75
+    },
+    {
+      "expression": "avg(array)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "avg('abc')",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "avg(foo)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "avg(@)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "avg(strings)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "ceil(`1.2`)",
+      "result": 2
+    },
+    {
+      "expression": "ceil(decimals[0])",
+      "result": 2
+    },
+    {
+      "expression": "ceil(decimals[1])",
+      "result": 2
+    },
+    {
+      "expression": "ceil(decimals[2])",
+      "result": -1
+    },
+    {
+      "expression": "ceil('string')",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "contains('abc', 'a')",
+      "result": true
+    },
+    {
+      "expression": "contains('abc', 'd')",
+      "result": false
+    },
+    {
+      "expression": "contains(`false`, 'd')",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "contains(strings, 'a')",
+      "result": true
+    },
+    {
+      "expression": "contains(decimals, `1.2`)",
+      "result": true
+    },
+    {
+      "expression": "contains(decimals, `false`)",
+      "result": false
+    },
+    {
+      "expression": "ends_with(str, 'r')",
+      "result": true
+    },
+    {
+      "expression": "ends_with(str, 'tr')",
+      "result": true
+    },
+    {
+      "expression": "ends_with(str, 'Str')",
+      "result": true
+    },
+    {
+      "expression": "ends_with(str, 'SStr')",
+      "result": false
+    },
+    {
+      "expression": "ends_with(str, 'foo')",
+      "result": false
+    },
+    {
+      "expression": "ends_with(str, `0`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "floor(`1.2`)",
+      "result": 1
+    },
+    {
+      "expression": "floor('string')",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "floor(decimals[0])",
+      "result": 1
+    },
+    {
+      "expression": "floor(foo)",
+      "result": -1
+    },
+    {
+      "expression": "floor(str)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "length('abc')",
+      "result": 3
+    },
+    {
+      "expression": "length('✓foo')",
+      "result": 4
+    },
+    {
+      "expression": "length('')",
+      "result": 0
+    },
+    {
+      "expression": "length(@)",
+      "result": 12
+    },
+    {
+      "expression": "length(strings[0])",
+      "result": 1
+    },
+    {
+      "expression": "length(str)",
+      "result": 3
+    },
+    {
+      "expression": "length(array)",
+      "result": 6
+    },
+    {
+      "expression": "length(objects)",
+      "result": 2
+    },
+    {
+      "expression": "length(`false`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "length(foo)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "length(strings[0])",
+      "result": 1
+    },
+    {
+      "expression": "max(numbers)",
+      "result": 5
+    },
+    {
+      "expression": "max(decimals)",
+      "result": 1.2
+    },
+    {
+      "expression": "max(strings)",
+      "result": "c"
+    },
+    {
+      "expression": "max(abc)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "max(array)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "max(decimals)",
+      "result": 1.2
+    },
+    {
+      "expression": "max(empty_list)",
+      "result": null
+    },
+    {
+      "expression": "merge(`{}`)",
+      "result": {}
+    },
+    {
+      "expression": "merge(`{}`, `{}`)",
+      "result": {}
+    },
+    {
+      "expression": "merge(`{\"a\": 1}`, `{\"b\": 2}`)",
+      "result": {"a": 1, "b": 2}
+    },
+    {
+      "expression": "merge(`{\"a\": 1}`, `{\"a\": 2}`)",
+      "result": {"a": 2}
+    },
+    {
+      "expression": "merge(`{\"a\": 1, \"b\": 2}`, `{\"a\": 2, \"c\": 3}`, `{\"d\": 4}`)",
+      "result": {"a": 2, "b": 2, "c": 3, "d": 4}
+    },
+    {
+      "expression": "min(numbers)",
+      "result": -1
+    },
+    {
+      "expression": "min(decimals)",
+      "result": -1.5
+    },
+    {
+      "expression": "min(abc)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "min(array)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "min(empty_list)",
+      "result": null
+    },
+    {
+      "expression": "min(decimals)",
+      "result": -1.5
+    },
+    {
+      "expression": "min(strings)",
+      "result": "a"
+    },
+    {
+      "expression": "type('abc')",
+      "result": "string"
+    },
+    {
+      "expression": "type(`1.0`)",
+      "result": "number"
+    },
+    {
+      "expression": "type(`2`)",
+      "result": "number"
+    },
+    {
+      "expression": "type(`true`)",
+      "result": "boolean"
+    },
+    {
+      "expression": "type(`false`)",
+      "result": "boolean"
+    },
+    {
+      "expression": "type(`null`)",
+      "result": "null"
+    },
+    {
+      "expression": "type(`[0]`)",
+      "result": "array"
+    },
+    {
+      "expression": "type(`{\"a\": \"b\"}`)",
+      "result": "object"
+    },
+    {
+      "expression": "type(@)",
+      "result": "object"
+    },
+    {
+      "expression": "sort(keys(objects))",
+      "result": ["bar", "foo"]
+    },
+    {
+      "expression": "keys(foo)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "keys(strings)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "keys(`false`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort(values(objects))",
+      "result": ["bar", "baz"]
+    },
+    {
+      "expression": "keys(empty_hash)",
+      "result": []
+    },
+    {
+      "expression": "values(foo)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "join(', ', strings)",
+      "result": "a, b, c"
+    },
+    {
+      "expression": "join(', ', strings)",
+      "result": "a, b, c"
+    },
+    {
+      "expression": "join(',', `[\"a\", \"b\"]`)",
+      "result": "a,b"
+    },
+    {
+      "expression": "join(',', `[\"a\", 0]`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "join(', ', str)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "join('|', strings)",
+      "result": "a|b|c"
+    },
+    {
+      "expression": "join(`2`, strings)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "join('|', decimals)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "join('|', decimals[].to_string(@))",
+      "result": "1.01|1.2|-1.5"
+    },
+    {
+      "expression": "join('|', empty_list)",
+      "result": ""
+    },
+    {
+      "expression": "reverse(numbers)",
+      "result": [5, 4, 3, -1]
+    },
+    {
+      "expression": "reverse(array)",
+      "result": ["100", "a", 5, 4, 3, -1]
+    },
+    {
+      "expression": "reverse(`[]`)",
+      "result": []
+    },
+    {
+      "expression": "reverse('')",
+      "result": ""
+    },
+    {
+      "expression": "reverse('hello world')",
+      "result": "dlrow olleh"
+    },
+    {
+      "expression": "starts_with(str, 'S')",
+      "result": true
+    },
+    {
+      "expression": "starts_with(str, 'St')",
+      "result": true
+    },
+    {
+      "expression": "starts_with(str, 'Str')",
+      "result": true
+    },
+    {
+      "expression": "starts_with(str, 'String')",
+      "result": false
+    },
+    {
+      "expression": "starts_with(str, `0`)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sum(numbers)",
+      "result": 11
+    },
+    {
+      "expression": "sum(decimals)",
+      "result": 0.71
+    },
+    {
+      "expression": "sum(array)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sum(array[].to_number(@))",
+      "result": 111
+    },
+    {
+      "expression": "sum(`[]`)",
+      "result": 0
+    },
+    {
+      "expression": "to_array('foo')",
+      "result": ["foo"]
+    },
+    {
+      "expression": "to_array(`0`)",
+      "result": [0]
+    },
+    {
+      "expression": "to_array(objects)",
+      "result": [{"foo": "bar", "bar": "baz"}]
+    },
+    {
+      "expression": "to_array(`[1, 2, 3]`)",
+      "result": [1, 2, 3]
+    },
+    {
+      "expression": "to_array(false)",
+      "result": [false]
+    },
+    {
+      "expression": "to_string('foo')",
+      "result": "foo"
+    },
+    {
+      "expression": "to_string(`1.2`)",
+      "result": "1.2"
+    },
+    {
+      "expression": "to_string(`[0, 1]`)",
+      "result": "[0,1]"
+    },
+    {
+      "expression": "to_number('1.0')",
+      "result": 1.0
+    },
+    {
+      "expression": "to_number('1.1')",
+      "result": 1.1
+    },
+    {
+      "expression": "to_number('4')",
+      "result": 4
+    },
+    {
+      "expression": "to_number('notanumber')",
+      "result": null
+    },
+    {
+      "expression": "to_number(`false`)",
+      "result": null
+    },
+    {
+      "expression": "to_number(`null`)",
+      "result": null
+    },
+    {
+      "expression": "to_number(`[0]`)",
+      "result": null
+    },
+    {
+      "expression": "to_number(`{\"foo\": 0}`)",
+      "result": null
+    },
+    {
+      "expression": "\"to_string\"(`1.0`)",
+      "error": "syntax"
+    },
+    {
+      "expression": "sort(numbers)",
+      "result": [-1, 3, 4, 5]
+    },
+    {
+      "expression": "sort(strings)",
+      "result": ["a", "b", "c"]
+    },
+    {
+      "expression": "sort(decimals)",
+      "result": [-1.5, 1.01, 1.2]
+    },
+    {
+      "expression": "sort(array)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort(abc)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort(empty_list)",
+      "result": []
+    },
+    {
+      "expression": "sort(@)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "not_null(unknown_key, str)",
+      "result": "Str"
+    },
+    {
+      "expression": "not_null(unknown_key, foo.bar, empty_list, str)",
+      "result": []
+    },
+    {
+      "expression": "not_null(unknown_key, null_key, empty_list, str)",
+      "result": []
+    },
+    {
+      "expression": "not_null(all, expressions, are_null)",
+      "result": null
+    },
+    {
+      "expression": "not_null()",
+      "error": "invalid-arity"
+    },
+    {
+      "description": "function projection on single arg function",
+      "expression": "numbers[].to_string(@)",
+      "result": ["-1", "3", "4", "5"]
+    },
+    {
+      "description": "function projection on single arg function",
+      "expression": "array[].to_number(@)",
+      "result": [-1, 3, 4, 5, 100]
+    }
+  ]
+}, {
+  "given":
+  {
+    "foo": [
+         {"b": "b", "a": "a"},
+         {"c": "c", "b": "b"},
+         {"d": "d", "c": "c"},
+         {"e": "e", "d": "d"},
+         {"f": "f", "e": "e"}
+    ]
+  },
+  "cases": [
+    {
+      "description": "function projection on variadic function",
+      "expression": "foo[].not_null(f, e, d, c, b, a)",
+      "result": ["b", "c", "d", "e", "f"]
+    }
+  ]
+}, {
+  "given":
+  {
+    "people": [
+         {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
+         {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
+         {"age": 30, "age_str": "30", "bool": true, "name": "c"},
+         {"age": 50, "age_str": "50", "bool": false, "name": "d"},
+         {"age": 10, "age_str": "10", "bool": true, "name": 3}
+    ]
+  },
+  "cases": [
+    {
+      "description": "sort by field expression",
+      "expression": "sort_by(people, &age)",
+      "result": [
+         {"age": 10, "age_str": "10", "bool": true, "name": 3},
+         {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
+         {"age": 30, "age_str": "30", "bool": true, "name": "c"},
+         {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
+         {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+      ]
+    },
+    {
+      "expression": "sort_by(people, &age_str)",
+      "result": [
+         {"age": 10, "age_str": "10", "bool": true, "name": 3},
+         {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
+         {"age": 30, "age_str": "30", "bool": true, "name": "c"},
+         {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
+         {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+      ]
+    },
+    {
+      "description": "sort by function expression",
+      "expression": "sort_by(people, &to_number(age_str))",
+      "result": [
+         {"age": 10, "age_str": "10", "bool": true, "name": 3},
+         {"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
+         {"age": 30, "age_str": "30", "bool": true, "name": "c"},
+         {"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
+         {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+      ]
+    },
+    {
+      "description": "function projection on sort_by function",
+      "expression": "sort_by(people, &age)[].name",
+      "result": [3, "a", "c", "b", "d"]
+    },
+    {
+      "expression": "sort_by(people, &extra)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort_by(people, &bool)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort_by(people, &name)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort_by(people, name)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "sort_by(people, &age)[].extra",
+      "result": ["foo", "bar"]
+    },
+    {
+      "expression": "sort_by(`[]`, &age)",
+      "result": []
+    },
+    {
+      "expression": "max_by(people, &age)",
+      "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+    },
+    {
+      "expression": "max_by(people, &age_str)",
+      "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+    },
+    {
+      "expression": "max_by(people, &bool)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "max_by(people, &extra)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "max_by(people, &to_number(age_str))",
+      "result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
+    },
+    {
+      "expression": "min_by(people, &age)",
+      "result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
+    },
+    {
+      "expression": "min_by(people, &age_str)",
+      "result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
+    },
+    {
+      "expression": "min_by(people, &bool)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "min_by(people, &extra)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "min_by(people, &to_number(age_str))",
+      "result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
+    }
+  ]
+}, {
+  "given":
+  {
+    "people": [
+         {"age": 10, "order": "1"},
+         {"age": 10, "order": "2"},
+         {"age": 10, "order": "3"},
+         {"age": 10, "order": "4"},
+         {"age": 10, "order": "5"},
+         {"age": 10, "order": "6"},
+         {"age": 10, "order": "7"},
+         {"age": 10, "order": "8"},
+         {"age": 10, "order": "9"},
+         {"age": 10, "order": "10"},
+         {"age": 10, "order": "11"}
+    ]
+  },
+  "cases": [
+    {
+      "description": "stable sort order",
+      "expression": "sort_by(people, &age)",
+      "result": [
+         {"age": 10, "order": "1"},
+         {"age": 10, "order": "2"},
+         {"age": 10, "order": "3"},
+         {"age": 10, "order": "4"},
+         {"age": 10, "order": "5"},
+         {"age": 10, "order": "6"},
+         {"age": 10, "order": "7"},
+         {"age": 10, "order": "8"},
+         {"age": 10, "order": "9"},
+         {"age": 10, "order": "10"},
+         {"age": 10, "order": "11"}
+      ]
+    }
+  ]
+}, {
+  "given":
+  {
+    "people": [
+         {"a": 10, "b": 1, "c": "z"},
+         {"a": 10, "b": 2, "c": null},
+         {"a": 10, "b": 3},
+         {"a": 10, "b": 4, "c": "z"},
+         {"a": 10, "b": 5, "c": null},
+         {"a": 10, "b": 6},
+         {"a": 10, "b": 7, "c": "z"},
+         {"a": 10, "b": 8, "c": null},
+         {"a": 10, "b": 9}
+    ],
+    "empty": []
+  },
+  "cases": [
+    {
+      "expression": "map(&a, people)",
+      "result": [10, 10, 10, 10, 10, 10, 10, 10, 10]
+    },
+    {
+      "expression": "map(&c, people)",
+      "result": ["z", null, null, "z", null, null, "z", null, null]
+    },
+    {
+      "expression": "map(&a, badkey)",
+      "error": "invalid-type"
+    },
+    {
+      "expression": "map(&foo, empty)",
+      "result": []
+    }
+  ]
+}, {
+  "given": {
+    "array": [
+      {
+          "foo": {"bar": "yes1"}
+      },
+      {
+          "foo": {"bar": "yes2"}
+      },
+      {
+          "foo1": {"bar": "no"}
+      }
+  ]},
+  "cases": [
+    {
+      "expression": "map(&foo.bar, array)",
+      "result": ["yes1", "yes2", null]
+    },
+    {
+      "expression": "map(&foo1.bar, array)",
+      "result": [null, null, "no"]
+    },
+    {
+      "expression": "map(&foo.bar.baz, array)",
+      "result": [null, null, null]
+    }
+  ]
+}, {
+  "given": {
+    "array": [[1, 2, 3, [4]], [5, 6, 7, [8, 9]]]
+  },
+  "cases": [
+    {
+      "expression": "map(&[], array)",
+      "result": [[1, 2, 3, 4], [5, 6, 7, 8, 9]]
+    }
+  ]
+}
+]

+ 1377 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/identifiers.json

@@ -0,0 +1,1377 @@
+[
+    {
+        "given": {
+            "__L": true
+        },
+        "cases": [
+            {
+                "expression": "__L",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "!\r": true
+        },
+        "cases": [
+            {
+                "expression": "\"!\\r\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Y_1623": true
+        },
+        "cases": [
+            {
+                "expression": "Y_1623",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "x": true
+        },
+        "cases": [
+            {
+                "expression": "x",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\tF\uCebb": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\tF\\uCebb\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            " \t": true
+        },
+        "cases": [
+            {
+                "expression": "\" \\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            " ": true
+        },
+        "cases": [
+            {
+                "expression": "\" \"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "v2": true
+        },
+        "cases": [
+            {
+                "expression": "v2",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_X": true
+        },
+        "cases": [
+            {
+                "expression": "_X",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\t4\ud9da\udd15": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\t4\\ud9da\\udd15\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "v24_W": true
+        },
+        "cases": [
+            {
+                "expression": "v24_W",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "H": true
+        },
+        "cases": [
+            {
+                "expression": "\"H\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\f": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\f\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "E4": true
+        },
+        "cases": [
+            {
+                "expression": "\"E4\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "!": true
+        },
+        "cases": [
+            {
+                "expression": "\"!\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "tM": true
+        },
+        "cases": [
+            {
+                "expression": "tM",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            " [": true
+        },
+        "cases": [
+            {
+                "expression": "\" [\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "R!": true
+        },
+        "cases": [
+            {
+                "expression": "\"R!\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_6W": true
+        },
+        "cases": [
+            {
+                "expression": "_6W",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\uaBA1\r": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\uaBA1\\r\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "tL7": true
+        },
+        "cases": [
+            {
+                "expression": "tL7",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "<<U\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"<<U\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\ubBcE\ufAfB": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\ubBcE\\ufAfB\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "sNA_": true
+        },
+        "cases": [
+            {
+                "expression": "sNA_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "9": true
+        },
+        "cases": [
+            {
+                "expression": "\"9\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\\\b\ud8cb\udc83": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\\\\b\\ud8cb\\udc83\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "r": true
+        },
+        "cases": [
+            {
+                "expression": "\"r\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Q": true
+        },
+        "cases": [
+            {
+                "expression": "Q",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_Q__7GL8": true
+        },
+        "cases": [
+            {
+                "expression": "_Q__7GL8",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\\": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\\\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "RR9_": true
+        },
+        "cases": [
+            {
+                "expression": "RR9_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\r\f:": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\r\\f:\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "r7": true
+        },
+        "cases": [
+            {
+                "expression": "r7",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "-": true
+        },
+        "cases": [
+            {
+                "expression": "\"-\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "p9": true
+        },
+        "cases": [
+            {
+                "expression": "p9",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "__": true
+        },
+        "cases": [
+            {
+                "expression": "__",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\b\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\b\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "O_": true
+        },
+        "cases": [
+            {
+                "expression": "O_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_r_8": true
+        },
+        "cases": [
+            {
+                "expression": "_r_8",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_j": true
+        },
+        "cases": [
+            {
+                "expression": "_j",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            ":": true
+        },
+        "cases": [
+            {
+                "expression": "\":\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\rB": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\rB\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Obf": true
+        },
+        "cases": [
+            {
+                "expression": "Obf",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\n": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\n\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\f\udb54\udf33": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\f\udb54\udf33\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\\\u4FDc": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\\\\u4FDc\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\r": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\r\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "m_": true
+        },
+        "cases": [
+            {
+                "expression": "m_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\r\fB ": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\r\\fB \"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "+\"\"": true
+        },
+        "cases": [
+            {
+                "expression": "\"+\\\"\\\"\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Mg": true
+        },
+        "cases": [
+            {
+                "expression": "Mg",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\"!\/": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\"!\\/\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "7\"": true
+        },
+        "cases": [
+            {
+                "expression": "\"7\\\"\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\\\udb3a\udca4S": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\\\udb3a\udca4S\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\"": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\"\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Kl": true
+        },
+        "cases": [
+            {
+                "expression": "Kl",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\b\b": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\b\\b\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            ">": true
+        },
+        "cases": [
+            {
+                "expression": "\">\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "hvu": true
+        },
+        "cases": [
+            {
+                "expression": "hvu",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "; !": true
+        },
+        "cases": [
+            {
+                "expression": "\"; !\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "hU": true
+        },
+        "cases": [
+            {
+                "expression": "hU",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "!I\n\/": true
+        },
+        "cases": [
+            {
+                "expression": "\"!I\\n\\/\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\uEEbF": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\uEEbF\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "U)\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"U)\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "fa0_9": true
+        },
+        "cases": [
+            {
+                "expression": "fa0_9",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "/": true
+        },
+        "cases": [
+            {
+                "expression": "\"/\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Gy": true
+        },
+        "cases": [
+            {
+                "expression": "Gy",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\b": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\b\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "<": true
+        },
+        "cases": [
+            {
+                "expression": "\"<\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\t&\\\r": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\t&\\\\\\r\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "#": true
+        },
+        "cases": [
+            {
+                "expression": "\"#\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "B__": true
+        },
+        "cases": [
+            {
+                "expression": "B__",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\nS \n": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\nS \\n\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Bp": true
+        },
+        "cases": [
+            {
+                "expression": "Bp",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            ",\t;": true
+        },
+        "cases": [
+            {
+                "expression": "\",\\t;\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "B_q": true
+        },
+        "cases": [
+            {
+                "expression": "B_q",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\/+\t\n\b!Z": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\/+\\t\\n\\b!Z\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\udadd\udfc7\\ueFAc": true
+        },
+        "cases": [
+            {
+                "expression": "\"\udadd\udfc7\\\\ueFAc\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            ":\f": true
+        },
+        "cases": [
+            {
+                "expression": "\":\\f\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\/": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\/\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_BW_6Hg_Gl": true
+        },
+        "cases": [
+            {
+                "expression": "_BW_6Hg_Gl",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\udbcf\udc02": true
+        },
+        "cases": [
+            {
+                "expression": "\"\udbcf\udc02\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "zs1DC": true
+        },
+        "cases": [
+            {
+                "expression": "zs1DC",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "__434": true
+        },
+        "cases": [
+            {
+                "expression": "__434",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\udb94\udd41": true
+        },
+        "cases": [
+            {
+                "expression": "\"\udb94\udd41\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Z_5": true
+        },
+        "cases": [
+            {
+                "expression": "Z_5",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "z_M_": true
+        },
+        "cases": [
+            {
+                "expression": "z_M_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "YU_2": true
+        },
+        "cases": [
+            {
+                "expression": "YU_2",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_0": true
+        },
+        "cases": [
+            {
+                "expression": "_0",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\b+": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\b+\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\"": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\"\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "D7": true
+        },
+        "cases": [
+            {
+                "expression": "D7",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_62L": true
+        },
+        "cases": [
+            {
+                "expression": "_62L",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\tK\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\tK\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\n\\\f": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\n\\\\\\f\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "I_": true
+        },
+        "cases": [
+            {
+                "expression": "I_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "W_a0_": true
+        },
+        "cases": [
+            {
+                "expression": "W_a0_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "BQ": true
+        },
+        "cases": [
+            {
+                "expression": "BQ",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\tX$\uABBb": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\tX$\\uABBb\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Z9": true
+        },
+        "cases": [
+            {
+                "expression": "Z9",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\b%\"\uda38\udd0f": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\b%\\\"\uda38\udd0f\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_F": true
+        },
+        "cases": [
+            {
+                "expression": "_F",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "!,": true
+        },
+        "cases": [
+            {
+                "expression": "\"!,\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\"!": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\"!\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "Hh": true
+        },
+        "cases": [
+            {
+                "expression": "Hh",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "&": true
+        },
+        "cases": [
+            {
+                "expression": "\"&\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "9\r\\R": true
+        },
+        "cases": [
+            {
+                "expression": "\"9\\r\\\\R\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "M_k": true
+        },
+        "cases": [
+            {
+                "expression": "M_k",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "!\b\n\udb06\ude52\"\"": true
+        },
+        "cases": [
+            {
+                "expression": "\"!\\b\\n\udb06\ude52\\\"\\\"\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "6": true
+        },
+        "cases": [
+            {
+                "expression": "\"6\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_7": true
+        },
+        "cases": [
+            {
+                "expression": "_7",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "0": true
+        },
+        "cases": [
+            {
+                "expression": "\"0\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\\8\\": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\\\8\\\\\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "b7eo": true
+        },
+        "cases": [
+            {
+                "expression": "b7eo",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "xIUo9": true
+        },
+        "cases": [
+            {
+                "expression": "xIUo9",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "5": true
+        },
+        "cases": [
+            {
+                "expression": "\"5\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "?": true
+        },
+        "cases": [
+            {
+                "expression": "\"?\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "sU": true
+        },
+        "cases": [
+            {
+                "expression": "sU",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "VH2&H\\\/": true
+        },
+        "cases": [
+            {
+                "expression": "\"VH2&H\\\\\\/\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_C": true
+        },
+        "cases": [
+            {
+                "expression": "_C",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "_": true
+        },
+        "cases": [
+            {
+                "expression": "_",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "<\t": true
+        },
+        "cases": [
+            {
+                "expression": "\"<\\t\"",
+                "result": true
+            }
+        ]
+    },
+    {
+        "given": {
+            "\uD834\uDD1E": true
+        },
+        "cases": [
+            {
+                "expression": "\"\\uD834\\uDD1E\"",
+                "result": true
+            }
+        ]
+    }
+]

+ 346 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/indices.json

@@ -0,0 +1,346 @@
+[{
+    "given":
+        {"foo": {"bar": ["zero", "one", "two"]}},
+     "cases": [
+         {
+            "expression": "foo.bar[0]",
+            "result": "zero"
+         },
+         {
+            "expression": "foo.bar[1]",
+            "result": "one"
+         },
+         {
+            "expression": "foo.bar[2]",
+            "result": "two"
+         },
+         {
+            "expression": "foo.bar[3]",
+            "result": null
+         },
+         {
+            "expression": "foo.bar[-1]",
+            "result": "two"
+         },
+         {
+            "expression": "foo.bar[-2]",
+            "result": "one"
+         },
+         {
+            "expression": "foo.bar[-3]",
+            "result": "zero"
+         },
+         {
+            "expression": "foo.bar[-4]",
+            "result": null
+         }
+     ]
+},
+{
+    "given":
+        {"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]},
+     "cases": [
+         {
+            "expression": "foo.bar",
+            "result": null
+         },
+         {
+            "expression": "foo[0].bar",
+            "result": "one"
+         },
+         {
+            "expression": "foo[1].bar",
+            "result": "two"
+         },
+         {
+            "expression": "foo[2].bar",
+            "result": "three"
+         },
+         {
+            "expression": "foo[3].notbar",
+            "result": "four"
+         },
+         {
+            "expression": "foo[3].bar",
+            "result": null
+         },
+         {
+            "expression": "foo[0]",
+            "result": {"bar": "one"}
+         },
+         {
+            "expression": "foo[1]",
+            "result": {"bar": "two"}
+         },
+         {
+            "expression": "foo[2]",
+            "result": {"bar": "three"}
+         },
+         {
+            "expression": "foo[3]",
+            "result": {"notbar": "four"}
+         },
+         {
+            "expression": "foo[4]",
+            "result": null
+         }
+     ]
+},
+{
+    "given": [
+        "one", "two", "three"
+    ],
+     "cases": [
+         {
+            "expression": "[0]",
+            "result": "one"
+         },
+         {
+            "expression": "[1]",
+            "result": "two"
+         },
+         {
+            "expression": "[2]",
+            "result": "three"
+         },
+         {
+            "expression": "[-1]",
+            "result": "three"
+         },
+         {
+            "expression": "[-2]",
+            "result": "two"
+         },
+         {
+            "expression": "[-3]",
+            "result": "one"
+         }
+     ]
+},
+{
+    "given": {"reservations": [
+        {"instances": [{"foo": 1}, {"foo": 2}]}
+    ]},
+    "cases": [
+        {
+           "expression": "reservations[].instances[].foo",
+           "result": [1, 2]
+        },
+        {
+           "expression": "reservations[].instances[].bar",
+           "result": []
+        },
+        {
+           "expression": "reservations[].notinstances[].foo",
+           "result": []
+        },
+        {
+           "expression": "reservations[].notinstances[].foo",
+           "result": []
+        }
+    ]
+},
+{
+    "given": {"reservations": [{
+        "instances": [
+            {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]},
+            {"foo": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]},
+            {"foo": "bar"},
+            {"notfoo": [{"bar": 20}, {"bar": 21}, {"notbar": [7]}, {"bar": 22}]},
+            {"bar": [{"baz": [1]}, {"baz": [2]}, {"baz": [3]}, {"baz": [4]}]},
+            {"baz": [{"baz": [1, 2]}, {"baz": []}, {"baz": []}, {"baz": [3, 4]}]},
+            {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]}
+        ],
+        "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}
+      }, {
+        "instances": [
+            {"a": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]},
+            {"b": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]},
+            {"c": "bar"},
+            {"notfoo": [{"bar": 23}, {"bar": 24}, {"notbar": [7]}, {"bar": 25}]},
+            {"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]}
+        ],
+        "otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}
+      }
+    ]},
+    "cases": [
+        {
+           "expression": "reservations[].instances[].foo[].bar",
+           "result": [1, 2, 4, 5, 6, 8]
+        },
+        {
+           "expression": "reservations[].instances[].foo[].baz",
+           "result": []
+        },
+        {
+           "expression": "reservations[].instances[].notfoo[].bar",
+           "result": [20, 21, 22, 23, 24, 25]
+        },
+        {
+           "expression": "reservations[].instances[].notfoo[].notbar",
+           "result": [[7], [7]]
+        },
+        {
+           "expression": "reservations[].notinstances[].foo",
+           "result": []
+        },
+        {
+           "expression": "reservations[].instances[].foo[].notbar",
+           "result": [3, [7]]
+        },
+        {
+           "expression": "reservations[].instances[].bar[].baz",
+           "result": [[1], [2], [3], [4]]
+        },
+        {
+           "expression": "reservations[].instances[].baz[].baz",
+           "result": [[1, 2], [], [], [3, 4]]
+        },
+        {
+           "expression": "reservations[].instances[].qux[].baz",
+           "result": [[], [1, 2, 3], [4], [], [], [1, 2, 3], [4], []]
+        },
+        {
+           "expression": "reservations[].instances[].qux[].baz[]",
+           "result": [1, 2, 3, 4, 1, 2, 3, 4]
+        }
+    ]
+},
+{
+    "given": {
+        "foo": [
+            [["one", "two"], ["three", "four"]],
+            [["five", "six"], ["seven", "eight"]],
+            [["nine"], ["ten"]]
+        ]
+     },
+    "cases": [
+        {
+           "expression": "foo[]",
+           "result": [["one", "two"], ["three", "four"], ["five", "six"],
+                      ["seven", "eight"], ["nine"], ["ten"]]
+        },
+        {
+           "expression": "foo[][0]",
+           "result": ["one", "three", "five", "seven", "nine", "ten"]
+        },
+        {
+           "expression": "foo[][1]",
+           "result": ["two", "four", "six", "eight"]
+        },
+        {
+           "expression": "foo[][0][0]",
+           "result": []
+        },
+         {
+            "expression": "foo[][2][2]",
+            "result": []
+         },
+         {
+            "expression": "foo[][0][0][100]",
+            "result": []
+         }
+    ]
+},
+{
+    "given": {
+      "foo": [{
+          "bar": [
+            {
+              "qux": 2,
+              "baz": 1
+            },
+            {
+              "qux": 4,
+              "baz": 3
+            }
+          ]
+        },
+        {
+          "bar": [
+            {
+              "qux": 6,
+              "baz": 5
+            },
+            {
+              "qux": 8,
+              "baz": 7
+            }
+          ]
+        }
+      ]
+    },
+    "cases": [
+        {
+           "expression": "foo",
+           "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
+                      {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
+        },
+        {
+           "expression": "foo[]",
+           "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
+                      {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
+        },
+        {
+           "expression": "foo[].bar",
+           "result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}],
+                      [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]]
+        },
+        {
+           "expression": "foo[].bar[]",
+           "result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3},
+                      {"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]
+        },
+        {
+           "expression": "foo[].bar[].baz",
+           "result": [1, 3, 5, 7]
+        }
+    ]
+},
+{
+    "given": {
+        "string": "string",
+        "hash": {"foo": "bar", "bar": "baz"},
+        "number": 23,
+        "nullvalue": null
+     },
+     "cases": [
+         {
+            "expression": "string[]",
+            "result": null
+         },
+         {
+            "expression": "hash[]",
+            "result": null
+         },
+         {
+            "expression": "number[]",
+            "result": null
+         },
+         {
+            "expression": "nullvalue[]",
+            "result": null
+         },
+         {
+            "expression": "string[].foo",
+            "result": null
+         },
+         {
+            "expression": "hash[].foo",
+            "result": null
+         },
+         {
+            "expression": "number[].foo",
+            "result": null
+         },
+         {
+            "expression": "nullvalue[].foo",
+            "result": null
+         },
+         {
+            "expression": "nullvalue[].foo[].bar",
+            "result": null
+         }
+     ]
+}
+]

+ 185 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/literal.json

@@ -0,0 +1,185 @@
+[
+    {
+        "given": {
+            "foo": [{"name": "a"}, {"name": "b"}],
+            "bar": {"baz": "qux"}
+        },
+        "cases": [
+            {
+                "expression": "`\"foo\"`",
+                "result": "foo"
+            },
+            {
+                "comment": "Interpret escaped unicode.",
+                "expression": "`\"\\u03a6\"`",
+                "result": "Φ"
+            },
+            {
+                "expression": "`\"✓\"`",
+                "result": "✓"
+            },
+            {
+                "expression": "`[1, 2, 3]`",
+                "result": [1, 2, 3]
+            },
+            {
+                "expression": "`{\"a\": \"b\"}`",
+                "result": {"a": "b"}
+            },
+            {
+                "expression": "`true`",
+                "result": true
+            },
+            {
+                "expression": "`false`",
+                "result": false
+            },
+            {
+                "expression": "`null`",
+                "result": null
+            },
+            {
+                "expression": "`0`",
+                "result": 0
+            },
+            {
+                "expression": "`1`",
+                "result": 1
+            },
+            {
+                "expression": "`2`",
+                "result": 2
+            },
+            {
+                "expression": "`3`",
+                "result": 3
+            },
+            {
+                "expression": "`4`",
+                "result": 4
+            },
+            {
+                "expression": "`5`",
+                "result": 5
+            },
+            {
+                "expression": "`6`",
+                "result": 6
+            },
+            {
+                "expression": "`7`",
+                "result": 7
+            },
+            {
+                "expression": "`8`",
+                "result": 8
+            },
+            {
+                "expression": "`9`",
+                "result": 9
+            },
+            {
+                "comment": "Escaping a backtick in quotes",
+                "expression": "`\"foo\\`bar\"`",
+                "result": "foo`bar"
+            },
+            {
+                "comment": "Double quote in literal",
+                "expression": "`\"foo\\\"bar\"`",
+                "result": "foo\"bar"
+            },
+            {
+                "expression": "`\"1\\`\"`",
+                "result": "1`"
+            },
+            {
+                "comment": "Multiple literal expressions with escapes",
+                "expression": "`\"\\\\\"`.{a:`\"b\"`}",
+                "result": {"a": "b"}
+            },
+            {
+                "comment": "literal . identifier",
+                "expression": "`{\"a\": \"b\"}`.a",
+                "result": "b"
+            },
+            {
+                "comment": "literal . identifier . identifier",
+                "expression": "`{\"a\": {\"b\": \"c\"}}`.a.b",
+                "result": "c"
+            },
+            {
+                "comment": "literal . identifier bracket-expr",
+                "expression": "`[0, 1, 2]`[1]",
+                "result": 1
+            }
+        ]
+    },
+    {
+      "comment": "Literals",
+      "given": {"type": "object"},
+      "cases": [
+        {
+          "comment": "Literal with leading whitespace",
+          "expression": "`  {\"foo\": true}`",
+          "result": {"foo": true}
+        },
+        {
+          "comment": "Literal with trailing whitespace",
+          "expression": "`{\"foo\": true}   `",
+          "result": {"foo": true}
+        },
+        {
+          "comment": "Literal on RHS of subexpr not allowed",
+          "expression": "foo.`\"bar\"`",
+          "error": "syntax"
+        }
+      ]
+    },
+    {
+      "comment": "Raw String Literals",
+      "given": {},
+      "cases": [
+        {
+          "expression": "'foo'",
+          "result": "foo"
+        },
+        {
+          "expression": "'  foo  '",
+          "result": "  foo  "
+        },
+        {
+          "expression": "'0'",
+          "result": "0"
+        },
+        {
+          "expression": "'newline\n'",
+          "result": "newline\n"
+        },
+        {
+          "expression": "'\n'",
+          "result": "\n"
+        },
+        {
+          "expression": "'✓'",
+	  "result": "✓"
+        },
+        {
+          "expression": "'𝄞'",
+	  "result": "𝄞"
+        },
+        {
+          "expression": "'  [foo]  '",
+          "result": "  [foo]  "
+        },
+        {
+          "expression": "'[foo]'",
+          "result": "[foo]"
+        },
+        {
+          "comment": "Do not interpret escaped unicode.",
+          "expression": "'\\u03a6'",
+          "result": "\\u03a6"
+        }
+      ]
+    }
+]

+ 393 - 0
Godeps/_workspace/src/github.com/jmespath/go-jmespath/compliance/multiselect.json

@@ -0,0 +1,393 @@
+[{
+    "given": {
+      "foo": {
+        "bar": "bar",
+        "baz": "baz",
+        "qux": "qux",
+        "nested": {
+          "one": {
+            "a": "first",
+            "b": "second",
+            "c": "third"
+          },
+          "two": {
+            "a": "first",
+            "b": "second",
+            "c": "third"
+          },
+          "three": {
+            "a": "first",
+            "b": "second",
+            "c": {"inner": "third"}
+          }
+        }
+      },
+      "bar": 1,
+      "baz": 2,
+      "qux\"": 3
+    },
+     "cases": [
+         {
+            "expression": "foo.{bar: bar}",
+            "result": {"bar": "bar"}
+         },
+         {
+            "expression": "foo.{\"bar\": bar}",
+            "result": {"bar": "bar"}
+         },
+         {
+            "expression": "foo.{\"foo.bar\": bar}",
+            "result": {"foo.bar": "bar"}
+         },
+         {
+            "expression": "foo.{bar: bar, baz: baz}",
+            "result": {"bar": "bar", "baz": "baz"}
+         },
+         {
+            "expression": "foo.{\"bar\": bar, \"baz\": baz}",
+            "result": {"bar": "bar", "baz": "baz"}
+         },
+         {
+            "expression": "{\"baz\": baz, \"qux\\\"\": \"qux\\\"\"}",
+            "result": {"baz": 2, "qux\"": 3}
+         },
+         {
+            "expression": "foo.{bar:bar,baz:baz}",
+            "result": {"bar": "bar", "baz": "baz"}
+         },
+         {
+            "expression": "foo.{bar: bar,qux: qux}",
+            "result": {"bar": "bar", "qux": "qux"}
+         },
+         {
+            "expression": "foo.{bar: bar, noexist: noexist}",
+            "result": {"bar": "bar", "noexist": null}
+         },
+         {
+            "expression": "foo.{noexist: noexist, alsonoexist: alsonoexist}",
+            "result": {"noexist": null, "alsonoexist": null}
+         },
+         {
+            "expression": "foo.badkey.{nokey: nokey, alsonokey: alsonokey}",
+            "result": null
+         },
+         {
+            "expression": "foo.nested.*.{a: a,b: b}",
+            "result": [{"a": "first", "b": "second"},
+                       {"a": "first", "b": "second"},
+                       {"a": "first", "b": "second"}]
+         },
+         {
+            "expression": "foo.nested.three.{a: a, cinner: c.inner}",
+            "result": {"a": "first", "cinner": "third"}
+         },
+         {
+            "expression": "foo.nested.three.{a: a, c: c.inner.bad.key}",
+            "result": {"a": "first", "c": null}
+         },
+         {
+            "expression": "foo.{a: nested.one.a, b: nested.two.b}",
+            "result": {"a": "first", "b": "second"}
+         },
+         {
+            "expression": "{bar: bar, baz: baz}",
+            "result": {"bar": 1, "baz": 2}
+         },
+         {
+            "expression": "{bar: bar}",
+            "result": {"bar": 1}
+         },
+         {
+            "expression": "{otherkey: bar}",
+            "result": {"otherkey": 1}
+         },
+         {
+            "expression": "{no: no, exist: exist}",
+            "result": {"no": null, "exist": null}
+         },
+         {
+            "expression": "foo.[bar]",
+            "result": ["bar"]
+         },
+         {
+            "expression": "foo.[bar,baz]",
+            "result": ["bar", "baz"]
+         },
+         {
+            "expression": "foo.[bar,qux]",
+            "result": ["bar", "qux"]
+         },
+         {
+            "expression": "foo.[bar,noexist]",
+            "result": ["bar", null]
+         },
+         {
+            "expression": "foo.[noexist,alsonoexist]",
+            "result": [null, null]
+         }
+     ]
+}, {
+    "given": {
+      "foo": {"bar": 1, "baz": [2, 3, 4]}
+    },
+    "cases": [
+         {
+            "expression": "foo.{bar:bar,baz:baz}",
+            "result": {"bar": 1, "baz": [2, 3, 4]}
+         },
+         {
+            "expression": "foo.[bar,baz[0]]",
+            "result": [1, 2]
+         },
+         {
+            "expression": "foo.[bar,baz[1]]",
+            "result": [1, 3]
+         },
+         {
+            "expression": "foo.[bar,baz[2]]",
+            "result": [1, 4]
+         },
+         {
+            "expression": "foo.[bar,baz[3]]",
+            "result": [1, null]
+         },
+         {
+            "expression": "foo.[bar[0],baz[3]]",
+            "result": [null, null]
+         }
+    ]
+}, {
+    "given": {
+      "foo": {"bar": 1, "baz": 2}
+    },
+    "cases": [
+         {
+            "expression": "foo.{bar: bar, baz: baz}",
+            "result": {"bar": 1, "baz": 2}
+         },
+         {
+            "expression": "foo.[bar,baz]",
+            "result": [1, 2]
+         }
+    ]
+}, {
+    "given": {
+      "foo": {
+          "bar": {"baz": [{"common": "first", "one": 1},
+                          {"common": "second", "two": 2}]},
+          "ignoreme": 1,
+          "includeme": true
+      }
+    },
+    "cases": [
+         {
+            "expression": "foo.{bar: bar.baz[1],includeme: includeme}",
+            "result": {"bar": {"common": "second", "two": 2}, "includeme": true}
+         },
+         {
+            "expression": "foo.{\"bar.baz.two\": bar.baz[1].two, includeme: includeme}",
+            "result": {"bar.baz.two": 2, "includeme": true}
+         },
+         {
+            "expression": "foo.[includeme, bar.baz[*].common]",
+            "result": [true, ["first", "second"]]
+         },
+         {
+            "expression": "foo.[includeme, bar.baz[*].none]",
+            "result": [true, []]
+         },
+         {
+            "expression": "foo.[includeme, bar.baz[].common]",
+            "result": [true, ["first", "second"]]
+         }
+    ]
+}, {
+    "given": {
+      "reservations": [{
+          "instances": [
+              {"id": "id1",
+               "name": "first"},
+              {"id": "id2",
+               "name": "second"}
+          ]}, {
+          "instances": [
+              {"id": "id3",
+               "name": "third"},
+              {"id": "id4",
+               "name": "fourth"}
+          ]}
+      ]},
+    "cases": [
+         {
+            "expression": "reservations[*].instances[*].{id: id, name: name}",
+            "result": [[{"id": "id1", "name": "first"}, {"id": "id2", "name": "second"}],
+                       [{"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"}]]
+         },
+         {
+            "expression": "reservations[].instances[].{id: id, name: name}",
+            "result": [{"id": "id1", "name": "first"},
+                       {"id": "id2", "name": "second"},
+                       {"id": "id3", "name": "third"},
+                       {"id": "id4", "name": "fourth"}]
+         },
+         {
+            "expression": "reservations[].instances[].[id, name]",
+            "result": [["id1", "first"],
+                       ["id2", "second"],
+                       ["id3", "third"],
+                       ["id4", "fourth"]]
+         }
+    ]
+},
+{
+    "given": {
+      "foo": [{
+          "bar": [
+            {
+              "qux": 2,
+              "baz": 1
+            },
+            {
+              "qux": 4,
+              "baz": 3
+            }
+          ]
+        },
+        {
+          "bar": [
+            {
+              "qux": 6,
+              "baz": 5
+            },
+            {
+              "qux": 8,
+              "baz": 7
+            }
+          ]
+        }
+      ]
+    },
+    "cases": [
+        {
+           "expression": "foo",
+           "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
+                      {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
+        },
+        {
+           "expression": "foo[]",
+           "result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
+                      {"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
+        },
+        {
+           "expression": "foo[].bar",
+           "result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}],
+                      [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]]
+        },
+        {
+           "expression": "foo[].bar[]",
+           "result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3},
+                      {"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]
+        },
+        {
+           "expression": "foo[].bar[].[baz, qux]",
+           "result": [[1, 2], [3, 4], [5, 6], [7, 8]]
+        },
+        {
+           "expression": "foo[].bar[].[baz]",
+           "result": [[1], [3], [5], [7]]
+        },
+        {
+           "expression": "foo[].bar[].[baz, qux][]",
+           "result": [1, 2, 3, 4, 5, 6, 7, 8]
+        }
+    ]
+},
+{
+    "given": {
+        "foo": {
+            "baz": [
+                {
+                    "bar": "abc"
+                }, {
+                    "bar": "def"
+                }
+            ],
+            "qux": ["zero"]
+        }
+    },
+    "cases": [
+        {
+           "expression": "foo.[baz[*].bar, qux[0]]",
+           "result": [["abc", "def"], "zero"]
+        }
+    ]
+},
+{
+    "given": {
+        "foo": {
+            "baz": [
+                {
+                    "bar": "a",
+                    "bam": "b",
+                    "boo": "c"
+                }, {
+                    "bar": "d",
+                    "bam": "e",
+                    "boo": "f"
+                }
+            ],
+            "qux": ["zero"]
+        }
+    },
+    "cases": [
+        {
+           "expression": "foo.[baz[*].[bar, boo], qux[0]]",
+           "result": [[["a", "c" ], ["d", "f" ]], "zero"]
+        }
+    ]
+},
+{
+    "given": {
+        "foo": {
+            "baz": [
+                {
+                    "bar": "a",
+                    "bam": "b",
+                    "boo": "c"
+                }, {
+                    "bar": "d",
+                    "bam": "e",
+                    "boo": "f"
+                }
+            ],
+            "qux": ["zero"]
+        }
+    },
+    "cases": [
+        {
+           "expression": "foo.[baz[*].not_there || baz[*].bar, qux[0]]",
+           "result": [["a", "d"], "zero"]
+        }
+    ]
+},
+{
+    "given": {"type": "object"},
+    "cases": [
+        {
+          "comment": "Nested multiselect",
+          "expression": "[[*],*]",
+          "result": [null, ["object"]]
+        }
+    ]
+},
+{
+    "given": [],
+    "cases": [
+        {
+          "comment": "Nested multiselect",
+          "expression": "[[*]]",
+          "result": [[]]
+        }
+    ]
+}
+]

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است