func ParseArbitraryKeyValues(input string, out map[string]string, sep string) error {
	input = strings.TrimSpace(input)
	if input == "" {
		return nil
	}
	if out == nil {
		return fmt.Errorf("'out' is nil")
	}
	inputBytes, err := base64.StdEncoding.DecodeString(input)
	if err == nil {
		input = string(inputBytes)
	}
	err = json.Unmarshal([]byte(input), &out)
	if err != nil {
		if err = ParseKeyValues(input, out, sep); err != nil {
			return errwrap.Wrapf("failed to parse the input: {{err}}", err)
		}
	}
	for key, value := range out {
		if key != "" && value == "" {
			return fmt.Errorf("invalid value for key %q", key)
		}
	}
	return nil
}
ParseArbitraryKeyValues parses arbitrary <key,value> tuples. The input
can be one of the following:
* JSON string
* Base64 encoded JSON string
* Comma separated list of `<key>=<value>` pairs
* Base64 encoded string containing comma separated list of
`<key>=<value>` pairs

Input will be parsed into the output parameter, which should
be a non-nil map[string]string.
package strutil
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"sort"
	"strings"
	"github.com/hashicorp/errwrap"
	glob "github.com/ryanuber/go-glob"
)
func StrListContainsGlob(haystack []string, needle string) bool {
	for _, item := range haystack {
		if glob.Glob(item, needle) {
			return true
		}
	}
	return false
}
func StrListContains(haystack []string, needle string) bool {
	for _, item := range haystack {
		if item == needle {
			return true
		}
	}
	return false
}
func StrListSubset(super, sub []string) bool {
	for _, item := range sub {
		if !StrListContains(super, item) {
			return false
		}
	}
	return true
}
func ParseDedupAndSortStrings(input string, sep string) []string {
	input = strings.TrimSpace(input)
	parsed := []string{}
	if input == "" {
		return parsed
	}
	return RemoveDuplicates(strings.Split(input, sep), false)
}
func ParseDedupLowercaseAndSortStrings(input string, sep string) []string {
	input = strings.TrimSpace(input)
	parsed := []string{}
	if input == "" {
		return parsed
	}
	return RemoveDuplicates(strings.Split(input, sep), true)
}
func ParseKeyValues(input string, out map[string]string, sep string) error {
	if out == nil {
		return fmt.Errorf("'out is nil")
	}
	keyValues := ParseDedupLowercaseAndSortStrings(input, sep)
	if len(keyValues) == 0 {
		return nil
	}
	for _, keyValue := range keyValues {
		shards := strings.Split(keyValue, "=")
		if len(shards) != 2 {
			return fmt.Errorf("invalid <key,value> format")
		}
		key := strings.TrimSpace(shards[0])
		value := strings.TrimSpace(shards[1])
		if key == "" || value == "" {
			return fmt.Errorf("invalid <key,value> pair: key: %q value: %q", key, value)
		}
		out[key] = value
	}
	return nil
}