// extra returns a slice of strings that are present in a slice s1 but not
// in a slice s2.
341288
func extra(s1, s2 []string) (extra []string) {
	for _, e := range s2 {
		// FIXME: https://github.com/mozilla/tls-observatory/issues/186
		if e == "ECDHE-ECDSA-CHACHA20-POLY1305-OLD" || e == "ECDHE-RSA-CHACHA20-POLY1305-OLD" {
			continue
		}
		if !contains(s1, e) {
			extra = append(extra, e)
		}
	}
	return
}
798165
func (s *CountService) LowercaseExpandedTerms(lowercaseExpandedTerms bool) *CountService {
	s.lowercaseExpandedTerms = &lowercaseExpandedTerms
	return s
}
1021770
func Deduplicate(in []string) []string {
	if len(in) == 0 {
		return in
	}
	out := make([]string, 0, len(in))
	seen := make(map[string]bool, len(in))
	for _, val := range in {
		if _, ok := seen[val]; !ok {
			out = append(out, val)
			seen[val] = true
		}
	}
	return out
}
383713
func HasExtension(filename string, extensions map[string]bool) bool {
	var ext string
	if e := filepath.Ext(filename); strings.HasPrefix(e, ".") {
		ext = e[1:]
	} else {
		return false
	}

	// Case-insensitive lookup.
	// Optimistically assume a short ASCII extension and be
	// allocation-free in that case.
	var buf [10]byte
	lower := buf[:0]
	const utf8RuneSelf = 0x80 // from utf8 package, but not importing it.
	for i := 0; i < len(ext); i++ {
		c := ext[i]
		if c >= utf8RuneSelf {
			// Slow path.
			return extensions[strings.ToLower(ext)]
		}
		if 'A' <= c && c <= 'Z' {
			lower = append(lower, c+('a'-'A'))
		} else {
			lower = append(lower, c)
		}
	}
	// The conversion from []byte to string doesn't allocate in
	// a map lookup.
	return extensions[string(lower)]
}
1105359
func (s String) Difference(s2 String) String {
	result := NewString()
	for key := range s {
		if !s2.Has(key) {
			result.Insert(key)
		}
	}
	return result
}
1168301
func contains(slice []string, str string) bool {
	for _, val := range slice {
		if val == strings.ToLower(str) {
			return true
		}
	}
	return false
}
1213840
func exclude(files []string, exclude ...string) []string {
	var s []string
Outer:
	for _, f := range files {
		for _, e := range exclude {
			if f == e {
				continue Outer
			}
		}
		s = append(s, f)
	}
	return s
}
370184
func remove(strs []string, s string) []string {
	for i, v := range strs {
		if s == v {
			strs[i] = strs[len(strs)-1]
			return strs[:len(strs)-1]
		}
	}
	return strs
}
1150765
func (t *Token) Extra(key string) interface{} {
	if raw, ok := t.raw.(map[string]interface{}); ok {
		return raw[key]
	}

	vals, ok := t.raw.(url.Values)
	if !ok {
		return nil
	}

	v := vals.Get(key)
	switch s := strings.TrimSpace(v); strings.Count(s, ".") {
	case 0: // Contains no "."; try to parse as int
		if i, err := strconv.ParseInt(s, 10, 64); err == nil {
			return i
		}
	case 1: // Contains a single "."; try to parse as float
		if f, err := strconv.ParseFloat(s, 64); err == nil {
			return f
		}
	}

	return v
}
871956
func (u uintSlice) Less(i, j int64) bool {
	return u[i] < u[j]
}
400846
func sizeOfExtras(extras []interface{}) (l uint8) {
	for _, e := range extras {
		switch e.(type) {
		default:
			panic(fmt.Sprintf("mc: unknown extra type (%T)", e))
		case uint8:
			l += 8 / 8
		case uint16:
			l += 16 / 8
		case uint32:
			l += 32 / 8
		case uint64:
			l += 64 / 8
		}
	}
	return
}
257607
func (s *Slice) Skip(n int64) (int64, error) {
	if n == 0 {
		return 0, nil
	}

	if len(*s) == 0 {
		return 0, io.EOF
	}
	if n >= int64(len(*s)) {
		n = int64(len(*s))
		*s = nil
	} else {
		*s = (*s)[int(n):]
	}
	return n, nil
}
623051
func Separate(s string, sep byte) (string, string) {
	i := MidIndex(s, sep)
	if i < 0 {
		return "", ""
	}

	return s[:i], s[i+1:]
}
760645
func dedupeStrings(s1, s2 []string) (r []string) {
	dedupe := make(map[string]bool)

	if len(s1) > 0 && len(s2) > 0 {
		for _, i := range s1 {
			dedupe[i] = true
		}
		for _, i := range s2 {
			dedupe[i] = true
		}

		for i := range dedupe {
			r = append(r, i)
		}
		// And then re-sort them
		sort.Strings(r)
	} else if len(s1) > 0 {
		r = s1
	} else if len(s2) > 0 {
		r = s2
	}

	return
}
507312
func (a *IntsRef) Less(other *IntsRef) bool {
	if a == other {
		return false
	}

	aInts := a.Ints
	aUpto := a.Offset
	bInts := other.Ints
	bUpto := other.Offset

	var aStop int
	if a.Length < other.Length {
		aStop = aUpto + a.Length
	} else {
		aStop = aUpto + other.Length
	}

	for aUpto < aStop {
		aInt := aInts[aUpto]
		aUpto++
		bInt := bInts[bUpto]
		bUpto++
		if aInt > bInt {
			return false
		} else if aInt < bInt {
			return true
		}
	}

	// one is a prefix of the other, or, they are equal:
	return a.Length < other.Length
}
345456
func (v ExtraValues) AppendTo(body *form.Values, keyParts []string) {
	for k, vs := range v.Values {
		for _, v := range vs {
			body.Add(form.FormatKey(append(keyParts, k)), v)
		}
	}
}
98893
func removeStringFromSlice(slice []string, val string) []string {
	for i, str := range slice {
		if str == val {
			slice = append(slice[:i], slice[i+1:]...)
		}
	}

	return slice
}