You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ge...@apache.org on 2018/03/23 13:50:47 UTC

[20/25] brooklyn-client git commit: Add vendor file and remove glide from build/readme

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/context.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/context.go b/cli/vendor/github.com/urfave/cli/context.go
new file mode 100644
index 0000000..0513d34
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/context.go
@@ -0,0 +1,388 @@
+package cli
+
+import (
+	"errors"
+	"flag"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// Context is a type that is passed through to
+// each Handler action in a cli application. Context
+// can be used to retrieve context-specific Args and
+// parsed command-line options.
+type Context struct {
+	App            *App
+	Command        Command
+	flagSet        *flag.FlagSet
+	setFlags       map[string]bool
+	globalSetFlags map[string]bool
+	parentContext  *Context
+}
+
+// Creates a new context. For use in when invoking an App or Command action.
+func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
+	return &Context{App: app, flagSet: set, parentContext: parentCtx}
+}
+
+// Looks up the value of a local int flag, returns 0 if no int flag exists
+func (c *Context) Int(name string) int {
+	return lookupInt(name, c.flagSet)
+}
+
+// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists
+func (c *Context) Duration(name string) time.Duration {
+	return lookupDuration(name, c.flagSet)
+}
+
+// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
+func (c *Context) Float64(name string) float64 {
+	return lookupFloat64(name, c.flagSet)
+}
+
+// Looks up the value of a local bool flag, returns false if no bool flag exists
+func (c *Context) Bool(name string) bool {
+	return lookupBool(name, c.flagSet)
+}
+
+// Looks up the value of a local boolT flag, returns false if no bool flag exists
+func (c *Context) BoolT(name string) bool {
+	return lookupBoolT(name, c.flagSet)
+}
+
+// Looks up the value of a local string flag, returns "" if no string flag exists
+func (c *Context) String(name string) string {
+	return lookupString(name, c.flagSet)
+}
+
+// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
+func (c *Context) StringSlice(name string) []string {
+	return lookupStringSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
+func (c *Context) IntSlice(name string) []int {
+	return lookupIntSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local generic flag, returns nil if no generic flag exists
+func (c *Context) Generic(name string) interface{} {
+	return lookupGeneric(name, c.flagSet)
+}
+
+// Looks up the value of a global int flag, returns 0 if no int flag exists
+func (c *Context) GlobalInt(name string) int {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupInt(name, fs)
+	}
+	return 0
+}
+
+// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
+func (c *Context) GlobalDuration(name string) time.Duration {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupDuration(name, fs)
+	}
+	return 0
+}
+
+// Looks up the value of a global bool flag, returns false if no bool flag exists
+func (c *Context) GlobalBool(name string) bool {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupBool(name, fs)
+	}
+	return false
+}
+
+// Looks up the value of a global string flag, returns "" if no string flag exists
+func (c *Context) GlobalString(name string) string {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupString(name, fs)
+	}
+	return ""
+}
+
+// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
+func (c *Context) GlobalStringSlice(name string) []string {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupStringSlice(name, fs)
+	}
+	return nil
+}
+
+// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
+func (c *Context) GlobalIntSlice(name string) []int {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupIntSlice(name, fs)
+	}
+	return nil
+}
+
+// Looks up the value of a global generic flag, returns nil if no generic flag exists
+func (c *Context) GlobalGeneric(name string) interface{} {
+	if fs := lookupGlobalFlagSet(name, c); fs != nil {
+		return lookupGeneric(name, fs)
+	}
+	return nil
+}
+
+// Returns the number of flags set
+func (c *Context) NumFlags() int {
+	return c.flagSet.NFlag()
+}
+
+// Determines if the flag was actually set
+func (c *Context) IsSet(name string) bool {
+	if c.setFlags == nil {
+		c.setFlags = make(map[string]bool)
+		c.flagSet.Visit(func(f *flag.Flag) {
+			c.setFlags[f.Name] = true
+		})
+	}
+	return c.setFlags[name] == true
+}
+
+// Determines if the global flag was actually set
+func (c *Context) GlobalIsSet(name string) bool {
+	if c.globalSetFlags == nil {
+		c.globalSetFlags = make(map[string]bool)
+		ctx := c
+		if ctx.parentContext != nil {
+			ctx = ctx.parentContext
+		}
+		for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
+			ctx.flagSet.Visit(func(f *flag.Flag) {
+				c.globalSetFlags[f.Name] = true
+			})
+		}
+	}
+	return c.globalSetFlags[name]
+}
+
+// Returns a slice of flag names used in this context.
+func (c *Context) FlagNames() (names []string) {
+	for _, flag := range c.Command.Flags {
+		name := strings.Split(flag.GetName(), ",")[0]
+		if name == "help" {
+			continue
+		}
+		names = append(names, name)
+	}
+	return
+}
+
+// Returns a slice of global flag names used by the app.
+func (c *Context) GlobalFlagNames() (names []string) {
+	for _, flag := range c.App.Flags {
+		name := strings.Split(flag.GetName(), ",")[0]
+		if name == "help" || name == "version" {
+			continue
+		}
+		names = append(names, name)
+	}
+	return
+}
+
+// Returns the parent context, if any
+func (c *Context) Parent() *Context {
+	return c.parentContext
+}
+
+type Args []string
+
+// Returns the command line arguments associated with the context.
+func (c *Context) Args() Args {
+	args := Args(c.flagSet.Args())
+	return args
+}
+
+// Returns the nth argument, or else a blank string
+func (a Args) Get(n int) string {
+	if len(a) > n {
+		return a[n]
+	}
+	return ""
+}
+
+// Returns the first argument, or else a blank string
+func (a Args) First() string {
+	return a.Get(0)
+}
+
+// Return the rest of the arguments (not the first one)
+// or else an empty string slice
+func (a Args) Tail() []string {
+	if len(a) >= 2 {
+		return []string(a)[1:]
+	}
+	return []string{}
+}
+
+// Checks if there are any arguments present
+func (a Args) Present() bool {
+	return len(a) != 0
+}
+
+// Swaps arguments at the given indexes
+func (a Args) Swap(from, to int) error {
+	if from >= len(a) || to >= len(a) {
+		return errors.New("index out of range")
+	}
+	a[from], a[to] = a[to], a[from]
+	return nil
+}
+
+func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
+	if ctx.parentContext != nil {
+		ctx = ctx.parentContext
+	}
+	for ; ctx != nil; ctx = ctx.parentContext {
+		if f := ctx.flagSet.Lookup(name); f != nil {
+			return ctx.flagSet
+		}
+	}
+	return nil
+}
+
+func lookupInt(name string, set *flag.FlagSet) int {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.Atoi(f.Value.String())
+		if err != nil {
+			return 0
+		}
+		return val
+	}
+
+	return 0
+}
+
+func lookupDuration(name string, set *flag.FlagSet) time.Duration {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := time.ParseDuration(f.Value.String())
+		if err == nil {
+			return val
+		}
+	}
+
+	return 0
+}
+
+func lookupFloat64(name string, set *flag.FlagSet) float64 {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseFloat(f.Value.String(), 64)
+		if err != nil {
+			return 0
+		}
+		return val
+	}
+
+	return 0
+}
+
+func lookupString(name string, set *flag.FlagSet) string {
+	f := set.Lookup(name)
+	if f != nil {
+		return f.Value.String()
+	}
+
+	return ""
+}
+
+func lookupStringSlice(name string, set *flag.FlagSet) []string {
+	f := set.Lookup(name)
+	if f != nil {
+		return (f.Value.(*StringSlice)).Value()
+
+	}
+
+	return nil
+}
+
+func lookupIntSlice(name string, set *flag.FlagSet) []int {
+	f := set.Lookup(name)
+	if f != nil {
+		return (f.Value.(*IntSlice)).Value()
+
+	}
+
+	return nil
+}
+
+func lookupGeneric(name string, set *flag.FlagSet) interface{} {
+	f := set.Lookup(name)
+	if f != nil {
+		return f.Value
+	}
+	return nil
+}
+
+func lookupBool(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return false
+		}
+		return val
+	}
+
+	return false
+}
+
+func lookupBoolT(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return true
+		}
+		return val
+	}
+
+	return false
+}
+
+func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
+	switch ff.Value.(type) {
+	case *StringSlice:
+	default:
+		set.Set(name, ff.Value.String())
+	}
+}
+
+func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
+	visited := make(map[string]bool)
+	set.Visit(func(f *flag.Flag) {
+		visited[f.Name] = true
+	})
+	for _, f := range flags {
+		parts := strings.Split(f.GetName(), ",")
+		if len(parts) == 1 {
+			continue
+		}
+		var ff *flag.Flag
+		for _, name := range parts {
+			name = strings.Trim(name, " ")
+			if visited[name] {
+				if ff != nil {
+					return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
+				}
+				ff = set.Lookup(name)
+			}
+		}
+		if ff == nil {
+			continue
+		}
+		for _, name := range parts {
+			name = strings.Trim(name, " ")
+			if !visited[name] {
+				copyFlag(name, ff, set)
+			}
+		}
+	}
+	return nil
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/context_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/context_test.go b/cli/vendor/github.com/urfave/cli/context_test.go
new file mode 100644
index 0000000..7f8e928
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/context_test.go
@@ -0,0 +1,113 @@
+package cli
+
+import (
+	"flag"
+	"testing"
+	"time"
+)
+
+func TestNewContext(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Int("myflag", 12, "doc")
+	globalSet := flag.NewFlagSet("test", 0)
+	globalSet.Int("myflag", 42, "doc")
+	globalCtx := NewContext(nil, globalSet, nil)
+	command := Command{Name: "mycommand"}
+	c := NewContext(nil, set, globalCtx)
+	c.Command = command
+	expect(t, c.Int("myflag"), 12)
+	expect(t, c.GlobalInt("myflag"), 42)
+	expect(t, c.Command.Name, "mycommand")
+}
+
+func TestContext_Int(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Int("myflag", 12, "doc")
+	c := NewContext(nil, set, nil)
+	expect(t, c.Int("myflag"), 12)
+}
+
+func TestContext_Duration(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Duration("myflag", time.Duration(12*time.Second), "doc")
+	c := NewContext(nil, set, nil)
+	expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
+}
+
+func TestContext_String(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.String("myflag", "hello world", "doc")
+	c := NewContext(nil, set, nil)
+	expect(t, c.String("myflag"), "hello world")
+}
+
+func TestContext_Bool(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	c := NewContext(nil, set, nil)
+	expect(t, c.Bool("myflag"), false)
+}
+
+func TestContext_BoolT(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", true, "doc")
+	c := NewContext(nil, set, nil)
+	expect(t, c.BoolT("myflag"), true)
+}
+
+func TestContext_Args(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	c := NewContext(nil, set, nil)
+	set.Parse([]string{"--myflag", "bat", "baz"})
+	expect(t, len(c.Args()), 2)
+	expect(t, c.Bool("myflag"), true)
+}
+
+func TestContext_IsSet(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	set.String("otherflag", "hello world", "doc")
+	globalSet := flag.NewFlagSet("test", 0)
+	globalSet.Bool("myflagGlobal", true, "doc")
+	globalCtx := NewContext(nil, globalSet, nil)
+	c := NewContext(nil, set, globalCtx)
+	set.Parse([]string{"--myflag", "bat", "baz"})
+	globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
+	expect(t, c.IsSet("myflag"), true)
+	expect(t, c.IsSet("otherflag"), false)
+	expect(t, c.IsSet("bogusflag"), false)
+	expect(t, c.IsSet("myflagGlobal"), false)
+}
+
+func TestContext_GlobalIsSet(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	set.String("otherflag", "hello world", "doc")
+	globalSet := flag.NewFlagSet("test", 0)
+	globalSet.Bool("myflagGlobal", true, "doc")
+	globalSet.Bool("myflagGlobalUnset", true, "doc")
+	globalCtx := NewContext(nil, globalSet, nil)
+	c := NewContext(nil, set, globalCtx)
+	set.Parse([]string{"--myflag", "bat", "baz"})
+	globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
+	expect(t, c.GlobalIsSet("myflag"), false)
+	expect(t, c.GlobalIsSet("otherflag"), false)
+	expect(t, c.GlobalIsSet("bogusflag"), false)
+	expect(t, c.GlobalIsSet("myflagGlobal"), true)
+	expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
+	expect(t, c.GlobalIsSet("bogusGlobal"), false)
+}
+
+func TestContext_NumFlags(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	set.String("otherflag", "hello world", "doc")
+	globalSet := flag.NewFlagSet("test", 0)
+	globalSet.Bool("myflagGlobal", true, "doc")
+	globalCtx := NewContext(nil, globalSet, nil)
+	c := NewContext(nil, set, globalCtx)
+	set.Parse([]string{"--myflag", "--otherflag=foo"})
+	globalSet.Parse([]string{"--myflagGlobal"})
+	expect(t, c.NumFlags(), 2)
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/flag.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/flag.go b/cli/vendor/github.com/urfave/cli/flag.go
new file mode 100644
index 0000000..e951c2d
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/flag.go
@@ -0,0 +1,546 @@
+package cli
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// This flag enables bash-completion for all commands and subcommands
+var BashCompletionFlag = BoolFlag{
+	Name: "generate-bash-completion",
+}
+
+// This flag prints the version for the application
+var VersionFlag = BoolFlag{
+	Name:  "version, v",
+	Usage: "print the version",
+}
+
+// This flag prints the help for all commands and subcommands
+// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
+// unless HideHelp is set to true)
+var HelpFlag = BoolFlag{
+	Name:  "help, h",
+	Usage: "show help",
+}
+
+// Flag is a common interface related to parsing flags in cli.
+// For more advanced flag parsing techniques, it is recommended that
+// this interface be implemented.
+type Flag interface {
+	fmt.Stringer
+	// Apply Flag settings to the given flag set
+	Apply(*flag.FlagSet)
+	GetName() string
+}
+
+func flagSet(name string, flags []Flag) *flag.FlagSet {
+	set := flag.NewFlagSet(name, flag.ContinueOnError)
+
+	for _, f := range flags {
+		f.Apply(set)
+	}
+	return set
+}
+
+func eachName(longName string, fn func(string)) {
+	parts := strings.Split(longName, ",")
+	for _, name := range parts {
+		name = strings.Trim(name, " ")
+		fn(name)
+	}
+}
+
+// Generic is a generic parseable type identified by a specific flag
+type Generic interface {
+	Set(value string) error
+	String() string
+}
+
+// GenericFlag is the flag type for types implementing Generic
+type GenericFlag struct {
+	Name   string
+	Value  Generic
+	Usage  string
+	EnvVar string
+}
+
+// String returns the string representation of the generic flag to display the
+// help text to the user (uses the String() method of the generic flag to show
+// the value)
+func (f GenericFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
+}
+
+func (f GenericFlag) FormatValueHelp() string {
+	if f.Value == nil {
+		return ""
+	}
+	s := f.Value.String()
+	if len(s) == 0 {
+		return ""
+	}
+	return fmt.Sprintf("\"%s\"", s)
+}
+
+// Apply takes the flagset and calls Set on the generic flag with the value
+// provided by the user for parsing by the flag
+func (f GenericFlag) Apply(set *flag.FlagSet) {
+	val := f.Value
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				val.Set(envVal)
+				break
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f GenericFlag) GetName() string {
+	return f.Name
+}
+
+// StringSlice is an opaque type for []string to satisfy flag.Value
+type StringSlice []string
+
+// Set appends the string value to the list of values
+func (f *StringSlice) Set(value string) error {
+	*f = append(*f, value)
+	return nil
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f *StringSlice) String() string {
+	return fmt.Sprintf("%s", *f)
+}
+
+// Value returns the slice of strings set by this flag
+func (f *StringSlice) Value() []string {
+	return *f
+}
+
+// StringSlice is a string flag that can be specified multiple times on the
+// command-line
+type StringSliceFlag struct {
+	Name   string
+	Value  *StringSlice
+	Usage  string
+	EnvVar string
+}
+
+// String returns the usage
+func (f StringSliceFlag) String() string {
+	firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+	pref := prefixFor(firstName)
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f StringSliceFlag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				newVal := &StringSlice{}
+				for _, s := range strings.Split(envVal, ",") {
+					s = strings.TrimSpace(s)
+					newVal.Set(s)
+				}
+				f.Value = newVal
+				break
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Value == nil {
+			f.Value = &StringSlice{}
+		}
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f StringSliceFlag) GetName() string {
+	return f.Name
+}
+
+// StringSlice is an opaque type for []int to satisfy flag.Value
+type IntSlice []int
+
+// Set parses the value into an integer and appends it to the list of values
+func (f *IntSlice) Set(value string) error {
+	tmp, err := strconv.Atoi(value)
+	if err != nil {
+		return err
+	} else {
+		*f = append(*f, tmp)
+	}
+	return nil
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f *IntSlice) String() string {
+	return fmt.Sprintf("%d", *f)
+}
+
+// Value returns the slice of ints set by this flag
+func (f *IntSlice) Value() []int {
+	return *f
+}
+
+// IntSliceFlag is an int flag that can be specified multiple times on the
+// command-line
+type IntSliceFlag struct {
+	Name   string
+	Value  *IntSlice
+	Usage  string
+	EnvVar string
+}
+
+// String returns the usage
+func (f IntSliceFlag) String() string {
+	firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+	pref := prefixFor(firstName)
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f IntSliceFlag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				newVal := &IntSlice{}
+				for _, s := range strings.Split(envVal, ",") {
+					s = strings.TrimSpace(s)
+					err := newVal.Set(s)
+					if err != nil {
+						fmt.Fprintf(os.Stderr, err.Error())
+					}
+				}
+				f.Value = newVal
+				break
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Value == nil {
+			f.Value = &IntSlice{}
+		}
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f IntSliceFlag) GetName() string {
+	return f.Name
+}
+
+// BoolFlag is a switch that defaults to false
+type BoolFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Destination *bool
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f BoolFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f BoolFlag) Apply(set *flag.FlagSet) {
+	val := false
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				envValBool, err := strconv.ParseBool(envVal)
+				if err == nil {
+					val = envValBool
+				}
+				break
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.BoolVar(f.Destination, name, val, f.Usage)
+			return
+		}
+		set.Bool(name, val, f.Usage)
+	})
+}
+
+func (f BoolFlag) GetName() string {
+	return f.Name
+}
+
+// BoolTFlag this represents a boolean flag that is true by default, but can
+// still be set to false by --some-flag=false
+type BoolTFlag struct {
+	Name        string
+	Usage       string
+	EnvVar      string
+	Destination *bool
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f BoolTFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f BoolTFlag) Apply(set *flag.FlagSet) {
+	val := true
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				envValBool, err := strconv.ParseBool(envVal)
+				if err == nil {
+					val = envValBool
+					break
+				}
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.BoolVar(f.Destination, name, val, f.Usage)
+			return
+		}
+		set.Bool(name, val, f.Usage)
+	})
+}
+
+func (f BoolTFlag) GetName() string {
+	return f.Name
+}
+
+// StringFlag represents a flag that takes as string value
+type StringFlag struct {
+	Name        string
+	Value       string
+	Usage       string
+	EnvVar      string
+	Destination *string
+}
+
+// String returns the usage
+func (f StringFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
+}
+
+func (f StringFlag) FormatValueHelp() string {
+	s := f.Value
+	if len(s) == 0 {
+		return ""
+	}
+	return fmt.Sprintf("\"%s\"", s)
+}
+
+// Apply populates the flag given the flag set and environment
+func (f StringFlag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				f.Value = envVal
+				break
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.StringVar(f.Destination, name, f.Value, f.Usage)
+			return
+		}
+		set.String(name, f.Value, f.Usage)
+	})
+}
+
+func (f StringFlag) GetName() string {
+	return f.Name
+}
+
+// IntFlag is a flag that takes an integer
+// Errors if the value provided cannot be parsed
+type IntFlag struct {
+	Name        string
+	Value       int
+	Usage       string
+	EnvVar      string
+	Destination *int
+}
+
+// String returns the usage
+func (f IntFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f IntFlag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				envValInt, err := strconv.ParseInt(envVal, 0, 64)
+				if err == nil {
+					f.Value = int(envValInt)
+					break
+				}
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.IntVar(f.Destination, name, f.Value, f.Usage)
+			return
+		}
+		set.Int(name, f.Value, f.Usage)
+	})
+}
+
+func (f IntFlag) GetName() string {
+	return f.Name
+}
+
+// DurationFlag is a flag that takes a duration specified in Go's duration
+// format: https://golang.org/pkg/time/#ParseDuration
+type DurationFlag struct {
+	Name        string
+	Value       time.Duration
+	Usage       string
+	EnvVar      string
+	Destination *time.Duration
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f DurationFlag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f DurationFlag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				envValDuration, err := time.ParseDuration(envVal)
+				if err == nil {
+					f.Value = envValDuration
+					break
+				}
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.DurationVar(f.Destination, name, f.Value, f.Usage)
+			return
+		}
+		set.Duration(name, f.Value, f.Usage)
+	})
+}
+
+func (f DurationFlag) GetName() string {
+	return f.Name
+}
+
+// Float64Flag is a flag that takes an float value
+// Errors if the value provided cannot be parsed
+type Float64Flag struct {
+	Name        string
+	Value       float64
+	Usage       string
+	EnvVar      string
+	Destination *float64
+}
+
+// String returns the usage
+func (f Float64Flag) String() string {
+	return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f Float64Flag) Apply(set *flag.FlagSet) {
+	if f.EnvVar != "" {
+		for _, envVar := range strings.Split(f.EnvVar, ",") {
+			envVar = strings.TrimSpace(envVar)
+			if envVal := os.Getenv(envVar); envVal != "" {
+				envValFloat, err := strconv.ParseFloat(envVal, 10)
+				if err == nil {
+					f.Value = float64(envValFloat)
+				}
+			}
+		}
+	}
+
+	eachName(f.Name, func(name string) {
+		if f.Destination != nil {
+			set.Float64Var(f.Destination, name, f.Value, f.Usage)
+			return
+		}
+		set.Float64(name, f.Value, f.Usage)
+	})
+}
+
+func (f Float64Flag) GetName() string {
+	return f.Name
+}
+
+func prefixFor(name string) (prefix string) {
+	if len(name) == 1 {
+		prefix = "-"
+	} else {
+		prefix = "--"
+	}
+
+	return
+}
+
+func prefixedNames(fullName string) (prefixed string) {
+	parts := strings.Split(fullName, ",")
+	for i, name := range parts {
+		name = strings.Trim(name, " ")
+		prefixed += prefixFor(name) + name
+		if i < len(parts)-1 {
+			prefixed += ", "
+		}
+	}
+	return
+}
+
+func withEnvHint(envVar, str string) string {
+	envText := ""
+	if envVar != "" {
+		prefix := "$"
+		suffix := ""
+		sep := ", $"
+		if runtime.GOOS == "windows" {
+			prefix = "%"
+			suffix = "%"
+			sep = "%, %"
+		}
+		envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix)
+	}
+	return str + envText
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/flag_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/flag_test.go b/cli/vendor/github.com/urfave/cli/flag_test.go
new file mode 100644
index 0000000..3caa70a
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/flag_test.go
@@ -0,0 +1,859 @@
+package cli
+
+import (
+	"fmt"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+	"runtime"
+)
+
+var boolFlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help\t"},
+	{"h", "-h\t"},
+}
+
+func TestBoolFlagHelpOutput(t *testing.T) {
+
+	for _, test := range boolFlagTests {
+		flag := BoolFlag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+var stringFlagTests = []struct {
+	name     string
+	value    string
+	expected string
+}{
+	{"help", "", "--help \t"},
+	{"h", "", "-h \t"},
+	{"h", "", "-h \t"},
+	{"test", "Something", "--test \"Something\"\t"},
+}
+
+func TestStringFlagHelpOutput(t *testing.T) {
+
+	for _, test := range stringFlagTests {
+		flag := StringFlag{Name: test.name, Value: test.value}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_FOO", "derp")
+	for _, test := range stringFlagTests {
+		flag := StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_FOO]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_FOO%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%s does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var stringSliceFlagTests = []struct {
+	name     string
+	value    *StringSlice
+	expected string
+}{
+	{"help", func() *StringSlice {
+		s := &StringSlice{}
+		s.Set("")
+		return s
+	}(), "--help [--help option --help option]\t"},
+	{"h", func() *StringSlice {
+		s := &StringSlice{}
+		s.Set("")
+		return s
+	}(), "-h [-h option -h option]\t"},
+	{"h", func() *StringSlice {
+		s := &StringSlice{}
+		s.Set("")
+		return s
+	}(), "-h [-h option -h option]\t"},
+	{"test", func() *StringSlice {
+		s := &StringSlice{}
+		s.Set("Something")
+		return s
+	}(), "--test [--test option --test option]\t"},
+}
+
+func TestStringSliceFlagHelpOutput(t *testing.T) {
+
+	for _, test := range stringSliceFlagTests {
+		flag := StringSliceFlag{Name: test.name, Value: test.value}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%q does not match %q", output, test.expected)
+		}
+	}
+}
+
+func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_QWWX", "11,4")
+	for _, test := range stringSliceFlagTests {
+		flag := StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_QWWX]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_QWWX%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%q does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var intFlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help \"0\"\t"},
+	{"h", "-h \"0\"\t"},
+}
+
+func TestIntFlagHelpOutput(t *testing.T) {
+
+	for _, test := range intFlagTests {
+		flag := IntFlag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_BAR", "2")
+	for _, test := range intFlagTests {
+		flag := IntFlag{Name: test.name, EnvVar: "APP_BAR"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_BAR]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_BAR%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%s does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var durationFlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help \"0\"\t"},
+	{"h", "-h \"0\"\t"},
+}
+
+func TestDurationFlagHelpOutput(t *testing.T) {
+
+	for _, test := range durationFlagTests {
+		flag := DurationFlag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_BAR", "2h3m6s")
+	for _, test := range durationFlagTests {
+		flag := DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_BAR]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_BAR%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%s does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var intSliceFlagTests = []struct {
+	name     string
+	value    *IntSlice
+	expected string
+}{
+	{"help", &IntSlice{}, "--help [--help option --help option]\t"},
+	{"h", &IntSlice{}, "-h [-h option -h option]\t"},
+	{"h", &IntSlice{}, "-h [-h option -h option]\t"},
+	{"test", func() *IntSlice {
+		i := &IntSlice{}
+		i.Set("9")
+		return i
+	}(), "--test [--test option --test option]\t"},
+}
+
+func TestIntSliceFlagHelpOutput(t *testing.T) {
+
+	for _, test := range intSliceFlagTests {
+		flag := IntSliceFlag{Name: test.name, Value: test.value}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%q does not match %q", output, test.expected)
+		}
+	}
+}
+
+func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_SMURF", "42,3")
+	for _, test := range intSliceFlagTests {
+		flag := IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_SMURF]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_SMURF%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%q does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var float64FlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help \"0\"\t"},
+	{"h", "-h \"0\"\t"},
+}
+
+func TestFloat64FlagHelpOutput(t *testing.T) {
+
+	for _, test := range float64FlagTests {
+		flag := Float64Flag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_BAZ", "99.4")
+	for _, test := range float64FlagTests {
+		flag := Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_BAZ]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_BAZ%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%s does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+var genericFlagTests = []struct {
+	name     string
+	value    Generic
+	expected string
+}{
+	{"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
+	{"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
+}
+
+func TestGenericFlagHelpOutput(t *testing.T) {
+
+	for _, test := range genericFlagTests {
+		flag := GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%q does not match %q", output, test.expected)
+		}
+	}
+}
+
+func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_ZAP", "3")
+	for _, test := range genericFlagTests {
+		flag := GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
+		output := flag.String()
+
+		expectedSuffix := " [$APP_ZAP]"
+		if runtime.GOOS == "windows" {
+			expectedSuffix = " [%APP_ZAP%]"
+		}
+		if !strings.HasSuffix(output, expectedSuffix) {
+			t.Errorf("%s does not end with" + expectedSuffix, output)
+		}
+	}
+}
+
+func TestParseMultiString(t *testing.T) {
+	(&App{
+		Flags: []Flag{
+			StringFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.String("serve") != "10" {
+				t.Errorf("main name not set")
+			}
+			if ctx.String("s") != "10" {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run", "-s", "10"})
+}
+
+func TestParseDestinationString(t *testing.T) {
+	var dest string
+	a := App{
+		Flags: []Flag{
+			StringFlag{
+				Name:        "dest",
+				Destination: &dest,
+			},
+		},
+		Action: func(ctx *Context) {
+			if dest != "10" {
+				t.Errorf("expected destination String 10")
+			}
+		},
+	}
+	a.Run([]string{"run", "--dest", "10"})
+}
+
+func TestParseMultiStringFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_COUNT", "20")
+	(&App{
+		Flags: []Flag{
+			StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.String("count") != "20" {
+				t.Errorf("main name not set")
+			}
+			if ctx.String("c") != "20" {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiStringFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_COUNT", "20")
+	(&App{
+		Flags: []Flag{
+			StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.String("count") != "20" {
+				t.Errorf("main name not set")
+			}
+			if ctx.String("c") != "20" {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiStringSlice(t *testing.T) {
+	(&App{
+		Flags: []Flag{
+			StringSliceFlag{Name: "serve, s", Value: &StringSlice{}},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
+				t.Errorf("main name not set")
+			}
+			if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiStringSliceFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_INTERVALS", "20,30,40")
+
+	(&App{
+		Flags: []Flag{
+			StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
+				t.Errorf("main name not set from env")
+			}
+			if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_INTERVALS", "20,30,40")
+
+	(&App{
+		Flags: []Flag{
+			StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
+				t.Errorf("main name not set from env")
+			}
+			if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiInt(t *testing.T) {
+	a := App{
+		Flags: []Flag{
+			IntFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Int("serve") != 10 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Int("s") != 10 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "-s", "10"})
+}
+
+func TestParseDestinationInt(t *testing.T) {
+	var dest int
+	a := App{
+		Flags: []Flag{
+			IntFlag{
+				Name:        "dest",
+				Destination: &dest,
+			},
+		},
+		Action: func(ctx *Context) {
+			if dest != 10 {
+				t.Errorf("expected destination Int 10")
+			}
+		},
+	}
+	a.Run([]string{"run", "--dest", "10"})
+}
+
+func TestParseMultiIntFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_TIMEOUT_SECONDS", "10")
+	a := App{
+		Flags: []Flag{
+			IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Int("timeout") != 10 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Int("t") != 10 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiIntFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_TIMEOUT_SECONDS", "10")
+	a := App{
+		Flags: []Flag{
+			IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Int("timeout") != 10 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Int("t") != 10 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiIntSlice(t *testing.T) {
+	(&App{
+		Flags: []Flag{
+			IntSliceFlag{Name: "serve, s", Value: &IntSlice{}},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
+				t.Errorf("main name not set")
+			}
+			if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiIntSliceFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_INTERVALS", "20,30,40")
+
+	(&App{
+		Flags: []Flag{
+			IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
+				t.Errorf("main name not set from env")
+			}
+			if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_INTERVALS", "20,30,40")
+
+	(&App{
+		Flags: []Flag{
+			IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
+				t.Errorf("main name not set from env")
+			}
+			if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}).Run([]string{"run"})
+}
+
+func TestParseMultiFloat64(t *testing.T) {
+	a := App{
+		Flags: []Flag{
+			Float64Flag{Name: "serve, s"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Float64("serve") != 10.2 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Float64("s") != 10.2 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "-s", "10.2"})
+}
+
+func TestParseDestinationFloat64(t *testing.T) {
+	var dest float64
+	a := App{
+		Flags: []Flag{
+			Float64Flag{
+				Name:        "dest",
+				Destination: &dest,
+			},
+		},
+		Action: func(ctx *Context) {
+			if dest != 10.2 {
+				t.Errorf("expected destination Float64 10.2")
+			}
+		},
+	}
+	a.Run([]string{"run", "--dest", "10.2"})
+}
+
+func TestParseMultiFloat64FromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
+	a := App{
+		Flags: []Flag{
+			Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Float64("timeout") != 15.5 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Float64("t") != 15.5 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
+	a := App{
+		Flags: []Flag{
+			Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Float64("timeout") != 15.5 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Float64("t") != 15.5 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiBool(t *testing.T) {
+	a := App{
+		Flags: []Flag{
+			BoolFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Bool("serve") != true {
+				t.Errorf("main name not set")
+			}
+			if ctx.Bool("s") != true {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "--serve"})
+}
+
+func TestParseDestinationBool(t *testing.T) {
+	var dest bool
+	a := App{
+		Flags: []Flag{
+			BoolFlag{
+				Name:        "dest",
+				Destination: &dest,
+			},
+		},
+		Action: func(ctx *Context) {
+			if dest != true {
+				t.Errorf("expected destination Bool true")
+			}
+		},
+	}
+	a.Run([]string{"run", "--dest"})
+}
+
+func TestParseMultiBoolFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_DEBUG", "1")
+	a := App{
+		Flags: []Flag{
+			BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Bool("debug") != true {
+				t.Errorf("main name not set from env")
+			}
+			if ctx.Bool("d") != true {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_DEBUG", "1")
+	a := App{
+		Flags: []Flag{
+			BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Bool("debug") != true {
+				t.Errorf("main name not set from env")
+			}
+			if ctx.Bool("d") != true {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolT(t *testing.T) {
+	a := App{
+		Flags: []Flag{
+			BoolTFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.BoolT("serve") != true {
+				t.Errorf("main name not set")
+			}
+			if ctx.BoolT("s") != true {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "--serve"})
+}
+
+func TestParseDestinationBoolT(t *testing.T) {
+	var dest bool
+	a := App{
+		Flags: []Flag{
+			BoolTFlag{
+				Name:        "dest",
+				Destination: &dest,
+			},
+		},
+		Action: func(ctx *Context) {
+			if dest != true {
+				t.Errorf("expected destination BoolT true")
+			}
+		},
+	}
+	a.Run([]string{"run", "--dest"})
+}
+
+func TestParseMultiBoolTFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_DEBUG", "0")
+	a := App{
+		Flags: []Flag{
+			BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.BoolT("debug") != false {
+				t.Errorf("main name not set from env")
+			}
+			if ctx.BoolT("d") != false {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_DEBUG", "0")
+	a := App{
+		Flags: []Flag{
+			BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.BoolT("debug") != false {
+				t.Errorf("main name not set from env")
+			}
+			if ctx.BoolT("d") != false {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+type Parser [2]string
+
+func (p *Parser) Set(value string) error {
+	parts := strings.Split(value, ",")
+	if len(parts) != 2 {
+		return fmt.Errorf("invalid format")
+	}
+
+	(*p)[0] = parts[0]
+	(*p)[1] = parts[1]
+
+	return nil
+}
+
+func (p *Parser) String() string {
+	return fmt.Sprintf("%s,%s", p[0], p[1])
+}
+
+func TestParseGeneric(t *testing.T) {
+	a := App{
+		Flags: []Flag{
+			GenericFlag{Name: "serve, s", Value: &Parser{}},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
+				t.Errorf("main name not set")
+			}
+			if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "-s", "10,20"})
+}
+
+func TestParseGenericFromEnv(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_SERVE", "20,30")
+	a := App{
+		Flags: []Flag{
+			GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
+				t.Errorf("main name not set from env")
+			}
+			if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
+				t.Errorf("short name not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}
+
+func TestParseGenericFromEnvCascade(t *testing.T) {
+	os.Clearenv()
+	os.Setenv("APP_FOO", "99,2000")
+	a := App{
+		Flags: []Flag{
+			GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
+		},
+		Action: func(ctx *Context) {
+			if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
+				t.Errorf("value not set from env")
+			}
+		},
+	}
+	a.Run([]string{"run"})
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/help.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/help.go b/cli/vendor/github.com/urfave/cli/help.go
new file mode 100644
index 0000000..15916f8
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/help.go
@@ -0,0 +1,248 @@
+package cli
+
+import (
+	"fmt"
+	"io"
+	"strings"
+	"text/tabwriter"
+	"text/template"
+)
+
+// The text template for the Default help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var AppHelpTemplate = `NAME:
+   {{.Name}} - {{.Usage}}
+
+USAGE:
+   {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
+   {{if .Version}}
+VERSION:
+   {{.Version}}
+   {{end}}{{if len .Authors}}
+AUTHOR(S):
+   {{range .Authors}}{{ . }}{{end}}
+   {{end}}{{if .Commands}}
+COMMANDS:
+   {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
+   {{end}}{{end}}{{if .Flags}}
+GLOBAL OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{end}}{{if .Copyright }}
+COPYRIGHT:
+   {{.Copyright}}
+   {{end}}
+`
+
+// The text template for the command help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var CommandHelpTemplate = `NAME:
+   {{.HelpName}} - {{.Usage}}
+
+USAGE:
+   {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}}
+
+DESCRIPTION:
+   {{.Description}}{{end}}{{if .Flags}}
+
+OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{ end }}
+`
+
+// The text template for the subcommand help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var SubcommandHelpTemplate = `NAME:
+   {{.HelpName}} - {{.Usage}}
+
+USAGE:
+   {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
+
+COMMANDS:
+   {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
+   {{end}}{{if .Flags}}
+OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{end}}
+`
+
+var helpCommand = Command{
+	Name:      "help",
+	Aliases:   []string{"h"},
+	Usage:     "Shows a list of commands or help for one command",
+	ArgsUsage: "[command]",
+	Action: func(c *Context) {
+		args := c.Args()
+		if args.Present() {
+			ShowCommandHelp(c, args.First())
+		} else {
+			ShowAppHelp(c)
+		}
+	},
+}
+
+var helpSubcommand = Command{
+	Name:      "help",
+	Aliases:   []string{"h"},
+	Usage:     "Shows a list of commands or help for one command",
+	ArgsUsage: "[command]",
+	Action: func(c *Context) {
+		args := c.Args()
+		if args.Present() {
+			ShowCommandHelp(c, args.First())
+		} else {
+			ShowSubcommandHelp(c)
+		}
+	},
+}
+
+// Prints help for the App or Command
+type helpPrinter func(w io.Writer, templ string, data interface{})
+
+var HelpPrinter helpPrinter = printHelp
+
+// Prints version for the App
+var VersionPrinter = printVersion
+
+func ShowAppHelp(c *Context) {
+	HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
+}
+
+// Prints the list of subcommands as the default app completion method
+func DefaultAppComplete(c *Context) {
+	for _, command := range c.App.Commands {
+		for _, name := range command.Names() {
+			fmt.Fprintln(c.App.Writer, name)
+		}
+	}
+}
+
+// Prints help for the given command
+func ShowCommandHelp(ctx *Context, command string) {
+	// show the subcommand help for a command with subcommands
+	if command == "" {
+		HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
+		return
+	}
+
+	for _, c := range ctx.App.Commands {
+		if c.HasName(command) {
+			HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
+			return
+		}
+	}
+
+	if ctx.App.CommandNotFound != nil {
+		ctx.App.CommandNotFound(ctx, command)
+	} else {
+		fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
+	}
+}
+
+// Prints help for the given subcommand
+func ShowSubcommandHelp(c *Context) {
+	ShowCommandHelp(c, c.Command.Name)
+}
+
+// Prints the version number of the App
+func ShowVersion(c *Context) {
+	VersionPrinter(c)
+}
+
+func printVersion(c *Context) {
+	fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
+}
+
+// Prints the lists of commands within a given context
+func ShowCompletions(c *Context) {
+	a := c.App
+	if a != nil && a.BashComplete != nil {
+		a.BashComplete(c)
+	}
+}
+
+// Prints the custom completions for a given command
+func ShowCommandCompletions(ctx *Context, command string) {
+	c := ctx.App.Command(command)
+	if c != nil && c.BashComplete != nil {
+		c.BashComplete(ctx)
+	}
+}
+
+func printHelp(out io.Writer, templ string, data interface{}) {
+	funcMap := template.FuncMap{
+		"join": strings.Join,
+	}
+
+	w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0)
+	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
+	err := t.Execute(w, data)
+	if err != nil {
+		// If the writer is closed, t.Execute will fail, and there's nothing
+		// we can do to recover. We could send this to os.Stderr if we need.
+		return
+	}
+	w.Flush()
+}
+
+func checkVersion(c *Context) bool {
+	found := false
+	if VersionFlag.Name != "" {
+		eachName(VersionFlag.Name, func(name string) {
+			if c.GlobalBool(name) || c.Bool(name) {
+				found = true
+			}
+		})
+	}
+	return found
+}
+
+func checkHelp(c *Context) bool {
+	found := false
+	if HelpFlag.Name != "" {
+		eachName(HelpFlag.Name, func(name string) {
+			if c.GlobalBool(name) || c.Bool(name) {
+				found = true
+			}
+		})
+	}
+	return found
+}
+
+func checkCommandHelp(c *Context, name string) bool {
+	if c.Bool("h") || c.Bool("help") {
+		ShowCommandHelp(c, name)
+		return true
+	}
+
+	return false
+}
+
+func checkSubcommandHelp(c *Context) bool {
+	if c.GlobalBool("h") || c.GlobalBool("help") {
+		ShowSubcommandHelp(c)
+		return true
+	}
+
+	return false
+}
+
+func checkCompletions(c *Context) bool {
+	if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
+		ShowCompletions(c)
+		return true
+	}
+
+	return false
+}
+
+func checkCommandCompletions(c *Context, name string) bool {
+	if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
+		ShowCommandCompletions(c, name)
+		return true
+	}
+
+	return false
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/help_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/help_test.go b/cli/vendor/github.com/urfave/cli/help_test.go
new file mode 100644
index 0000000..350e263
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/help_test.go
@@ -0,0 +1,94 @@
+package cli
+
+import (
+	"bytes"
+	"testing"
+)
+
+func Test_ShowAppHelp_NoAuthor(t *testing.T) {
+	output := new(bytes.Buffer)
+	app := NewApp()
+	app.Writer = output
+
+	c := NewContext(app, nil, nil)
+
+	ShowAppHelp(c)
+
+	if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
+		t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
+	}
+}
+
+func Test_ShowAppHelp_NoVersion(t *testing.T) {
+	output := new(bytes.Buffer)
+	app := NewApp()
+	app.Writer = output
+
+	app.Version = ""
+
+	c := NewContext(app, nil, nil)
+
+	ShowAppHelp(c)
+
+	if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 {
+		t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:")
+	}
+}
+
+func Test_Help_Custom_Flags(t *testing.T) {
+	oldFlag := HelpFlag
+	defer func() {
+		HelpFlag = oldFlag
+	}()
+
+	HelpFlag = BoolFlag{
+		Name:  "help, x",
+		Usage: "show help",
+	}
+
+	app := App{
+		Flags: []Flag{
+			BoolFlag{Name: "foo, h"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Bool("h") != true {
+				t.Errorf("custom help flag not set")
+			}
+		},
+	}
+	output := new(bytes.Buffer)
+	app.Writer = output
+	app.Run([]string{"test", "-h"})
+	if output.Len() > 0 {
+		t.Errorf("unexpected output: %s", output.String())
+	}
+}
+
+func Test_Version_Custom_Flags(t *testing.T) {
+	oldFlag := VersionFlag
+	defer func() {
+		VersionFlag = oldFlag
+	}()
+
+	VersionFlag = BoolFlag{
+		Name:  "version, V",
+		Usage: "show version",
+	}
+
+	app := App{
+		Flags: []Flag{
+			BoolFlag{Name: "foo, v"},
+		},
+		Action: func(ctx *Context) {
+			if ctx.Bool("v") != true {
+				t.Errorf("custom version flag not set")
+			}
+		},
+	}
+	output := new(bytes.Buffer)
+	app.Writer = output
+	app.Run([]string{"test", "-v"})
+	if output.Len() > 0 {
+		t.Errorf("unexpected output: %s", output.String())
+	}
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/helpers_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/helpers_test.go b/cli/vendor/github.com/urfave/cli/helpers_test.go
new file mode 100644
index 0000000..b1b7339
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/helpers_test.go
@@ -0,0 +1,19 @@
+package cli
+
+import (
+	"reflect"
+	"testing"
+)
+
+/* Test Helpers */
+func expect(t *testing.T, a interface{}, b interface{}) {
+	if !reflect.DeepEqual(a, b) {
+		t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+	}
+}
+
+func refute(t *testing.T, a interface{}, b interface{}) {
+	if reflect.DeepEqual(a, b) {
+		t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+	}
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/.gitattributes
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/.gitattributes b/cli/vendor/golang.org/x/crypto/.gitattributes
new file mode 100644
index 0000000..d2f212e
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/.gitattributes
@@ -0,0 +1,10 @@
+# Treat all files in this repo as binary, with no git magic updating
+# line endings. Windows users contributing to Go will need to use a
+# modern version of git and editors capable of LF line endings.
+#
+# We'll prevent accidental CRLF line endings from entering the repo
+# via the git-review gofmt checks.
+#
+# See golang.org/issue/9281
+
+* -text

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/.gitignore
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/.gitignore b/cli/vendor/golang.org/x/crypto/.gitignore
new file mode 100644
index 0000000..8339fd6
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/.gitignore
@@ -0,0 +1,2 @@
+# Add no patterns to .hgignore except for files generated by the build.
+last-change

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/AUTHORS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/AUTHORS b/cli/vendor/golang.org/x/crypto/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md b/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
new file mode 100644
index 0000000..88dff59
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+**We do not accept GitHub pull requests**
+(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
+

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/CONTRIBUTORS b/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/LICENSE
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/LICENSE b/cli/vendor/golang.org/x/crypto/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/PATENTS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/PATENTS b/cli/vendor/golang.org/x/crypto/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google 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,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/README
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/README b/cli/vendor/golang.org/x/crypto/README
new file mode 100644
index 0000000..f1e0cbf
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/README
@@ -0,0 +1,3 @@
+This repository holds supplementary Go cryptography libraries.
+
+To submit changes to this repository, see http://golang.org/doc/contribute.html.

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/base64.go b/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
new file mode 100644
index 0000000..fc31160
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
@@ -0,0 +1,35 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bcrypt
+
+import "encoding/base64"
+
+const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+var bcEncoding = base64.NewEncoding(alphabet)
+
+func base64Encode(src []byte) []byte {
+	n := bcEncoding.EncodedLen(len(src))
+	dst := make([]byte, n)
+	bcEncoding.Encode(dst, src)
+	for dst[n-1] == '=' {
+		n--
+	}
+	return dst[:n]
+}
+
+func base64Decode(src []byte) ([]byte, error) {
+	numOfEquals := 4 - (len(src) % 4)
+	for i := 0; i < numOfEquals; i++ {
+		src = append(src, '=')
+	}
+
+	dst := make([]byte, bcEncoding.DecodedLen(len(src)))
+	n, err := bcEncoding.Decode(dst, src)
+	if err != nil {
+		return nil, err
+	}
+	return dst[:n], nil
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
new file mode 100644
index 0000000..f8b807f
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
@@ -0,0 +1,294 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
+// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
+package bcrypt // import "golang.org/x/crypto/bcrypt"
+
+// The code is a port of Provos and Mazières's C implementation.
+import (
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"fmt"
+	"golang.org/x/crypto/blowfish"
+	"io"
+	"strconv"
+)
+
+const (
+	MinCost     int = 4  // the minimum allowable cost as passed in to GenerateFromPassword
+	MaxCost     int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
+	DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
+)
+
+// The error returned from CompareHashAndPassword when a password and hash do
+// not match.
+var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
+
+// The error returned from CompareHashAndPassword when a hash is too short to
+// be a bcrypt hash.
+var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
+
+// The error returned from CompareHashAndPassword when a hash was created with
+// a bcrypt algorithm newer than this implementation.
+type HashVersionTooNewError byte
+
+func (hv HashVersionTooNewError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
+}
+
+// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
+type InvalidHashPrefixError byte
+
+func (ih InvalidHashPrefixError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
+}
+
+type InvalidCostError int
+
+func (ic InvalidCostError) Error() string {
+	return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
+}
+
+const (
+	majorVersion       = '2'
+	minorVersion       = 'a'
+	maxSaltSize        = 16
+	maxCryptedHashSize = 23
+	encodedSaltSize    = 22
+	encodedHashSize    = 31
+	minHashSize        = 59
+)
+
+// magicCipherData is an IV for the 64 Blowfish encryption calls in
+// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
+var magicCipherData = []byte{
+	0x4f, 0x72, 0x70, 0x68,
+	0x65, 0x61, 0x6e, 0x42,
+	0x65, 0x68, 0x6f, 0x6c,
+	0x64, 0x65, 0x72, 0x53,
+	0x63, 0x72, 0x79, 0x44,
+	0x6f, 0x75, 0x62, 0x74,
+}
+
+type hashed struct {
+	hash  []byte
+	salt  []byte
+	cost  int // allowed range is MinCost to MaxCost
+	major byte
+	minor byte
+}
+
+// GenerateFromPassword returns the bcrypt hash of the password at the given
+// cost. If the cost given is less than MinCost, the cost will be set to
+// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
+// to compare the returned hashed password with its cleartext version.
+func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+	p, err := newFromPassword(password, cost)
+	if err != nil {
+		return nil, err
+	}
+	return p.Hash(), nil
+}
+
+// CompareHashAndPassword compares a bcrypt hashed password with its possible
+// plaintext equivalent. Returns nil on success, or an error on failure.
+func CompareHashAndPassword(hashedPassword, password []byte) error {
+	p, err := newFromHash(hashedPassword)
+	if err != nil {
+		return err
+	}
+
+	otherHash, err := bcrypt(password, p.cost, p.salt)
+	if err != nil {
+		return err
+	}
+
+	otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
+	if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
+		return nil
+	}
+
+	return ErrMismatchedHashAndPassword
+}
+
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+	p, err := newFromHash(hashedPassword)
+	if err != nil {
+		return 0, err
+	}
+	return p.cost, nil
+}
+
+func newFromPassword(password []byte, cost int) (*hashed, error) {
+	if cost < MinCost {
+		cost = DefaultCost
+	}
+	p := new(hashed)
+	p.major = majorVersion
+	p.minor = minorVersion
+
+	err := checkCost(cost)
+	if err != nil {
+		return nil, err
+	}
+	p.cost = cost
+
+	unencodedSalt := make([]byte, maxSaltSize)
+	_, err = io.ReadFull(rand.Reader, unencodedSalt)
+	if err != nil {
+		return nil, err
+	}
+
+	p.salt = base64Encode(unencodedSalt)
+	hash, err := bcrypt(password, p.cost, p.salt)
+	if err != nil {
+		return nil, err
+	}
+	p.hash = hash
+	return p, err
+}
+
+func newFromHash(hashedSecret []byte) (*hashed, error) {
+	if len(hashedSecret) < minHashSize {
+		return nil, ErrHashTooShort
+	}
+	p := new(hashed)
+	n, err := p.decodeVersion(hashedSecret)
+	if err != nil {
+		return nil, err
+	}
+	hashedSecret = hashedSecret[n:]
+	n, err = p.decodeCost(hashedSecret)
+	if err != nil {
+		return nil, err
+	}
+	hashedSecret = hashedSecret[n:]
+
+	// The "+2" is here because we'll have to append at most 2 '=' to the salt
+	// when base64 decoding it in expensiveBlowfishSetup().
+	p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
+	copy(p.salt, hashedSecret[:encodedSaltSize])
+
+	hashedSecret = hashedSecret[encodedSaltSize:]
+	p.hash = make([]byte, len(hashedSecret))
+	copy(p.hash, hashedSecret)
+
+	return p, nil
+}
+
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
+	cipherData := make([]byte, len(magicCipherData))
+	copy(cipherData, magicCipherData)
+
+	c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
+	if err != nil {
+		return nil, err
+	}
+
+	for i := 0; i < 24; i += 8 {
+		for j := 0; j < 64; j++ {
+			c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
+		}
+	}
+
+	// Bug compatibility with C bcrypt implementations. We only encode 23 of
+	// the 24 bytes encrypted.
+	hsh := base64Encode(cipherData[:maxCryptedHashSize])
+	return hsh, nil
+}
+
+func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
+
+	csalt, err := base64Decode(salt)
+	if err != nil {
+		return nil, err
+	}
+
+	// Bug compatibility with C bcrypt implementations. They use the trailing
+	// NULL in the key string during expansion.
+	ckey := append(key, 0)
+
+	c, err := blowfish.NewSaltedCipher(ckey, csalt)
+	if err != nil {
+		return nil, err
+	}
+
+	var i, rounds uint64
+	rounds = 1 << cost
+	for i = 0; i < rounds; i++ {
+		blowfish.ExpandKey(ckey, c)
+		blowfish.ExpandKey(csalt, c)
+	}
+
+	return c, nil
+}
+
+func (p *hashed) Hash() []byte {
+	arr := make([]byte, 60)
+	arr[0] = '$'
+	arr[1] = p.major
+	n := 2
+	if p.minor != 0 {
+		arr[2] = p.minor
+		n = 3
+	}
+	arr[n] = '$'
+	n += 1
+	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
+	n += 2
+	arr[n] = '$'
+	n += 1
+	copy(arr[n:], p.salt)
+	n += encodedSaltSize
+	copy(arr[n:], p.hash)
+	n += encodedHashSize
+	return arr[:n]
+}
+
+func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
+	if sbytes[0] != '$' {
+		return -1, InvalidHashPrefixError(sbytes[0])
+	}
+	if sbytes[1] > majorVersion {
+		return -1, HashVersionTooNewError(sbytes[1])
+	}
+	p.major = sbytes[1]
+	n := 3
+	if sbytes[2] != '$' {
+		p.minor = sbytes[2]
+		n++
+	}
+	return n, nil
+}
+
+// sbytes should begin where decodeVersion left off.
+func (p *hashed) decodeCost(sbytes []byte) (int, error) {
+	cost, err := strconv.Atoi(string(sbytes[0:2]))
+	if err != nil {
+		return -1, err
+	}
+	err = checkCost(cost)
+	if err != nil {
+		return -1, err
+	}
+	p.cost = cost
+	return 3, nil
+}
+
+func (p *hashed) String() string {
+	return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
+}
+
+func checkCost(cost int) error {
+	if cost < MinCost || cost > MaxCost {
+		return InvalidCostError(cost)
+	}
+	return nil
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
new file mode 100644
index 0000000..f08a6f5
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
@@ -0,0 +1,226 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bcrypt
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+)
+
+func TestBcryptingIsEasy(t *testing.T) {
+	pass := []byte("mypassword")
+	hp, err := GenerateFromPassword(pass, 0)
+	if err != nil {
+		t.Fatalf("GenerateFromPassword error: %s", err)
+	}
+
+	if CompareHashAndPassword(hp, pass) != nil {
+		t.Errorf("%v should hash %s correctly", hp, pass)
+	}
+
+	notPass := "notthepass"
+	err = CompareHashAndPassword(hp, []byte(notPass))
+	if err != ErrMismatchedHashAndPassword {
+		t.Errorf("%v and %s should be mismatched", hp, notPass)
+	}
+}
+
+func TestBcryptingIsCorrect(t *testing.T) {
+	pass := []byte("allmine")
+	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+	expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
+
+	hash, err := bcrypt(pass, 10, salt)
+	if err != nil {
+		t.Fatalf("bcrypt blew up: %v", err)
+	}
+	if !bytes.HasSuffix(expectedHash, hash) {
+		t.Errorf("%v should be the suffix of %v", hash, expectedHash)
+	}
+
+	h, err := newFromHash(expectedHash)
+	if err != nil {
+		t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
+	}
+
+	// This is not the safe way to compare these hashes. We do this only for
+	// testing clarity. Use bcrypt.CompareHashAndPassword()
+	if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
+		t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash)
+	}
+}
+
+func TestVeryShortPasswords(t *testing.T) {
+	key := []byte("k")
+	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+	_, err := bcrypt(key, 10, salt)
+	if err != nil {
+		t.Errorf("One byte key resulted in error: %s", err)
+	}
+}
+
+func TestTooLongPasswordsWork(t *testing.T) {
+	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+	// One byte over the usual 56 byte limit that blowfish has
+	tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456")
+	tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C")
+	hash, err := bcrypt(tooLongPass, 10, salt)
+	if err != nil {
+		t.Fatalf("bcrypt blew up on long password: %v", err)
+	}
+	if !bytes.HasSuffix(tooLongExpected, hash) {
+		t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
+	}
+}
+
+type InvalidHashTest struct {
+	err  error
+	hash []byte
+}
+
+var invalidTests = []InvalidHashTest{
+	{ErrHashTooShort, []byte("$2a$10$fooo")},
+	{ErrHashTooShort, []byte("$2a")},
+	{HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+	{InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+	{InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+}
+
+func TestInvalidHashErrors(t *testing.T) {
+	check := func(name string, expected, err error) {
+		if err == nil {
+			t.Errorf("%s: Should have returned an error", name)
+		}
+		if err != nil && err != expected {
+			t.Errorf("%s gave err %v but should have given %v", name, err, expected)
+		}
+	}
+	for _, iht := range invalidTests {
+		_, err := newFromHash(iht.hash)
+		check("newFromHash", iht.err, err)
+		err = CompareHashAndPassword(iht.hash, []byte("anything"))
+		check("CompareHashAndPassword", iht.err, err)
+	}
+}
+
+func TestUnpaddedBase64Encoding(t *testing.T) {
+	original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30}
+	encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")
+
+	encoded := base64Encode(original)
+
+	if !bytes.Equal(encodedOriginal, encoded) {
+		t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal)
+	}
+
+	decoded, err := base64Decode(encodedOriginal)
+	if err != nil {
+		t.Fatalf("base64Decode blew up: %s", err)
+	}
+
+	if !bytes.Equal(decoded, original) {
+		t.Errorf("Decoded %v should have equaled %v", decoded, original)
+	}
+}
+
+func TestCost(t *testing.T) {
+	suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C"
+	for _, vers := range []string{"2a", "2"} {
+		for _, cost := range []int{4, 10} {
+			s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix)
+			h := []byte(s)
+			actual, err := Cost(h)
+			if err != nil {
+				t.Errorf("Cost, error: %s", err)
+				continue
+			}
+			if actual != cost {
+				t.Errorf("Cost, expected: %d, actual: %d", cost, actual)
+			}
+		}
+	}
+	_, err := Cost([]byte("$a$a$" + suffix))
+	if err == nil {
+		t.Errorf("Cost, malformed but no error returned")
+	}
+}
+
+func TestCostValidationInHash(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	pass := []byte("mypassword")
+
+	for c := 0; c < MinCost; c++ {
+		p, _ := newFromPassword(pass, c)
+		if p.cost != DefaultCost {
+			t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
+		}
+	}
+
+	p, _ := newFromPassword(pass, 14)
+	if p.cost != 14 {
+		t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost)
+	}
+
+	hp, _ := newFromHash(p.Hash())
+	if p.cost != hp.cost {
+		t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost)
+	}
+
+	_, err := newFromPassword(pass, 32)
+	if err == nil {
+		t.Fatalf("newFromPassword: should return a cost error")
+	}
+	if err != InvalidCostError(32) {
+		t.Errorf("newFromPassword: should return cost error, got %#v", err)
+	}
+}
+
+func TestCostReturnsWithLeadingZeroes(t *testing.T) {
+	hp, _ := newFromPassword([]byte("abcdefgh"), 7)
+	cost := hp.Hash()[4:7]
+	expected := []byte("07$")
+
+	if !bytes.Equal(expected, cost) {
+		t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
+	}
+}
+
+func TestMinorNotRequired(t *testing.T) {
+	noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
+	h, err := newFromHash(noMinorHash)
+	if err != nil {
+		t.Fatalf("No minor hash blew up: %s", err)
+	}
+	if h.minor != 0 {
+		t.Errorf("Should leave minor version at 0, but was %d", h.minor)
+	}
+
+	if !bytes.Equal(noMinorHash, h.Hash()) {
+		t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
+	}
+}
+
+func BenchmarkEqual(b *testing.B) {
+	b.StopTimer()
+	passwd := []byte("somepasswordyoulike")
+	hash, _ := GenerateFromPassword(passwd, 10)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		CompareHashAndPassword(hash, passwd)
+	}
+}
+
+func BenchmarkGeneration(b *testing.B) {
+	b.StopTimer()
+	passwd := []byte("mylongpassword1234")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		GenerateFromPassword(passwd, 10)
+	}
+}