text:
package starlark

// This file defines the library of built-ins.
//
// Built-ins must explicitly check the "frozen" flag before updating
// mutable types such as lists and dicts.

import (
	"errors"
	"fmt"
	"math"
	"math/big"
	"os"
	"sort"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf16"
	"unicode/utf8"

	"go.starlark.net/syntax"
)

// Universe defines the set of universal built-ins, such as None, True, and len.
//
// The Go application may add or remove items from the
// universe dictionary before Starlark evaluation begins.
// All values in the dictionary must be immutable.
// Starlark programs cannot modify the dictionary.
var Universe StringDict

func init() {
	// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-constants-and-functions
	Universe = StringDict{
		"None":      None,
		"True":      True,
		"False":     False,
		"abs":       NewBuiltin("abs", abs),
		"any":       NewBuiltin("any", any),
		"all":       NewBuiltin("all", all),
		"bool":      NewBuiltin("bool", bool_),
		"bytes":     NewBuiltin("bytes", bytes_),
		"chr":       NewBuiltin("chr", chr),
		"dict":      NewBuiltin("dict", dict),
		"dir":       NewBuiltin("dir", dir),
		"enumerate": NewBuiltin("enumerate", enumerate),
		"fail":      NewBuiltin("fail", fail),
		"float":     NewBuiltin("float", float),
		"getattr":   NewBuiltin("getattr", getattr),
		"hasattr":   NewBuiltin("hasattr", hasattr),
		"hash":      NewBuiltin("hash", hash),
		"int":       NewBuiltin("int", int_),
		"len":       NewBuiltin("len", len_),
		"list":      NewBuiltin("list", list),
		"max":       NewBuiltin("max", minmax),
		"min":       NewBuiltin("min", minmax),
		"ord":       NewBuiltin("ord", ord),
		"print":     NewBuiltin("print", print),
		"range":     NewBuiltin("range", range_),
		"repr":      NewBuiltin("repr", repr),
		"reversed":  NewBuiltin("reversed", reversed),
		"set":       NewBuiltin("set", set), // requires resolve.AllowSet
		"sorted":    NewBuiltin("sorted", sorted),
		"str":       NewBuiltin("str", str),
		"tuple":     NewBuiltin("tuple", tuple),
		"type":      NewBuiltin("type", type_),
		"zip":       NewBuiltin("zip", zip),
	}
}

// methods of built-in types
// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-methods
var (
	bytesMethods = map[string]*Builtin{
		"elems": NewBuiltin("elems", bytes_elems),
	}

	dictMethods = map[string]*Builtin{
		"clear":      NewBuiltin("clear", dict_clear),
		"get":        NewBuiltin("get", dict_get),
		"items":      NewBuiltin("items", dict_items),
		"keys":       NewBuiltin("keys", dict_keys),
		"pop":        NewBuiltin("pop", dict_pop),
		"popitem":    NewBuiltin("popitem", dict_popitem),
		"setdefault": NewBuiltin("setdefault", dict_setdefault),
		"update":     NewBuiltin("update", dict_update),
		"values":     NewBuiltin("values", dict_values),
	}

	listMethods = map[string]*Builtin{
		"append": NewBuiltin("append", list_append),
		"clear":  NewBuiltin("clear", list_clear),
		"extend": NewBuiltin("extend", list_extend),
		"index":  NewBuiltin("index", list_index),
		"insert": NewBuiltin("insert", list_insert),
		"pop":    NewBuiltin("pop", list_pop),
		"remove": NewBuiltin("remove", list_remove),
	}

	stringMethods = map[string]*Builtin{
		"capitalize":     NewBuiltin("capitalize", string_capitalize),
		"codepoint_ords": NewBuiltin("codepoint_ords", string_iterable),
		"codepoints":     NewBuiltin("codepoints", string_iterable), // sic
		"count":          NewBuiltin("count", string_count),
		"elem_ords":      NewBuiltin("elem_ords", string_iterable),
		"elems":          NewBuiltin("elems", string_iterable),      // sic
		"endswith":       NewBuiltin("endswith", string_startswith), // sic
		"find":           NewBuiltin("find", string_find),
		"format":         NewBuiltin("format", string_format),
		"index":          NewBuiltin("index", string_index),
		"isalnum":        NewBuiltin("isalnum", string_isalnum),
		"isalpha":        NewBuiltin("isalpha", string_isalpha),
		"isdigit":        NewBuiltin("isdigit", string_isdigit),
		"islower":        NewBuiltin("islower", string_islower),
		"isspace":        NewBuiltin("isspace", string_isspace),
		"istitle":        NewBuiltin("istitle", string_istitle),
		"isupper":        NewBuiltin("isupper", string_isupper),
		"join":           NewBuiltin("join", string_join),
		"lower":          NewBuiltin("lower", string_lower),
		"lstrip":         NewBuiltin("lstrip", string_strip), // sic
		"partition":      NewBuiltin("partition", string_partition),
		"replace":        NewBuiltin("replace", string_replace),
		"rfind":          NewBuiltin("rfind", string_rfind),
		"rindex":         NewBuiltin("rindex", string_rindex),
		"rpartition":     NewBuiltin("rpartition", string_partition), // sic
		"rsplit":         NewBuiltin("rsplit", string_split),         // sic
		"rstrip":         NewBuiltin("rstrip", string_strip),         // sic
		"split":          NewBuiltin("split", string_split),
		"splitlines":     NewBuiltin("splitlines", string_splitlines),
		"startswith":     NewBuiltin("startswith", string_startswith),
		"strip":          NewBuiltin("strip", string_strip),
		"title":          NewBuiltin("title", string_title),
		"upper":          NewBuiltin("upper", string_upper),
	}

	setMethods = map[string]*Builtin{
		"union": NewBuiltin("union", set_union),
	}
)

func builtinAttr(recv Value, name string, methods map[string]*Builtin) (Value, error) {
	b := methods[name]
	if b == nil {
		return nil, nil // no such method
	}
	return b.BindReceiver(recv), nil
}

func builtinAttrNames(methods map[string]*Builtin) []string {
	names := make([]string, 0, len(methods))
	for name := range methods {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

// ---- built-in functions ----

// https://github.com/google/starlark-go/blob/master/doc/spec.md#abs
func abs(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value
	if err := UnpackPositionalArgs("abs", args, kwargs, 1, &x); err != nil {
		return nil, err
	}
	switch x := x.(type) {
	case Float:
		return Float(math.Abs(float64(x))), nil
	case Int:
		if x.Sign() >= 0 {
			return x, nil
		}
		return zero.Sub(x), nil
	default:
		return nil, fmt.Errorf("got %s, want int or float", x.Type())
	}
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#all
func all(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("all", args, kwargs, 1, &iterable); err != nil {
		return nil, err
	}
	iter := iterable.Iterate()
	defer iter.Done()
	var x Value
	for iter.Next(&x) {
		if !x.Truth() {
			return False, nil
		}
	}
	return True, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#any
func any(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("any", args, kwargs, 1, &iterable); err != nil {
		return nil, err
	}
	iter := iterable.Iterate()
	defer iter.Done()
	var x Value
	for iter.Next(&x) {
		if x.Truth() {
			return True, nil
		}
	}
	return False, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#bool
func bool_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value = False
	if err := UnpackPositionalArgs("bool", args, kwargs, 0, &x); err != nil {
		return nil, err
	}
	return x.Truth(), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#bytes
func bytes_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("bytes does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("bytes: got %d arguments, want exactly 1", len(args))
	}
	switch x := args[0].(type) {
	case Bytes:
		return x, nil
	case String:
		// Invalid encodings are replaced by that of U+FFFD.
		return Bytes(utf8Transcode(string(x))), nil
	case Iterable:
		// iterable of numeric byte values
		var buf strings.Builder
		if n := Len(x); n >= 0 {
			// common case: known length
			buf.Grow(n)
		}
		iter := x.Iterate()
		defer iter.Done()
		var elem Value
		var b byte
		for i := 0; iter.Next(&elem); i++ {
			if err := AsInt(elem, &b); err != nil {
				return nil, fmt.Errorf("bytes: at index %d, %s", i, err)
			}
			buf.WriteByte(b)
		}
		return Bytes(buf.String()), nil

	default:
		// Unlike string(foo), which stringifies it, bytes(foo) is an error.
		return nil, fmt.Errorf("bytes: got %s, want string, bytes, or iterable of ints", x.Type())
	}
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#chr
func chr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("chr does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("chr: got %d arguments, want 1", len(args))
	}
	i, err := AsInt32(args[0])
	if err != nil {
		return nil, fmt.Errorf("chr: %s", err)
	}
	if i < 0 {
		return nil, fmt.Errorf("chr: Unicode code point %d out of range (<0)", i)
	}
	if i > unicode.MaxRune {
		return nil, fmt.Errorf("chr: Unicode code point U+%X out of range (>0x10FFFF)", i)
	}
	return String(string(rune(i))), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict
func dict(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(args) > 1 {
		return nil, fmt.Errorf("dict: got %d arguments, want at most 1", len(args))
	}
	dict := new(Dict)
	if err := updateDict(dict, args, kwargs); err != nil {
		return nil, fmt.Errorf("dict: %v", err)
	}
	return dict, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dir
func dir(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("dir does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("dir: got %d arguments, want 1", len(args))
	}

	var names []string
	if x, ok := args[0].(HasAttrs); ok {
		names = x.AttrNames()
	}
	sort.Strings(names)
	elems := make([]Value, len(names))
	for i, name := range names {
		elems[i] = String(name)
	}
	return NewList(elems), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#enumerate
func enumerate(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	var start int
	if err := UnpackPositionalArgs("enumerate", args, kwargs, 1, &iterable, &start); err != nil {
		return nil, err
	}

	iter := iterable.Iterate()
	defer iter.Done()

	var pairs []Value
	var x Value

	if n := Len(iterable); n >= 0 {
		// common case: known length
		pairs = make([]Value, 0, n)
		array := make(Tuple, 2*n) // allocate a single backing array
		for i := 0; iter.Next(&x); i++ {
			pair := array[:2:2]
			array = array[2:]
			pair[0] = MakeInt(start + i)
			pair[1] = x
			pairs = append(pairs, pair)
		}
	} else {
		// non-sequence (unknown length)
		for i := 0; iter.Next(&x); i++ {
			pair := Tuple{MakeInt(start + i), x}
			pairs = append(pairs, pair)
		}
	}

	return NewList(pairs), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#fail
func fail(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	sep := " "
	if err := UnpackArgs("fail", nil, kwargs, "sep?", &sep); err != nil {
		return nil, err
	}
	buf := new(strings.Builder)
	buf.WriteString("fail: ")
	for i, v := range args {
		if i > 0 {
			buf.WriteString(sep)
		}
		if s, ok := AsString(v); ok {
			buf.WriteString(s)
		} else {
			writeValue(buf, v, nil)
		}
	}

	return nil, errors.New(buf.String())
}

func float(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("float does not accept keyword arguments")
	}
	if len(args) == 0 {
		return Float(0.0), nil
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("float got %d arguments, wants 1", len(args))
	}
	switch x := args[0].(type) {
	case Bool:
		if x {
			return Float(1.0), nil
		} else {
			return Float(0.0), nil
		}
	case Int:
		return x.finiteFloat()
	case Float:
		return x, nil
	case String:
		if x == "" {
			return nil, fmt.Errorf("float: empty string")
		}
		// +/- NaN or Inf or Infinity (case insensitive)?
		s := string(x)
		switch x[len(x)-1] {
		case 'y', 'Y':
			if strings.EqualFold(s, "infinity") || strings.EqualFold(s, "+infinity") {
				return inf, nil
			} else if strings.EqualFold(s, "-infinity") {
				return neginf, nil
			}
		case 'f', 'F':
			if strings.EqualFold(s, "inf") || strings.EqualFold(s, "+inf") {
				return inf, nil
			} else if strings.EqualFold(s, "-inf") {
				return neginf, nil
			}
		case 'n', 'N':
			if strings.EqualFold(s, "nan") || strings.EqualFold(s, "+nan") || strings.EqualFold(s, "-nan") {
				return nan, nil
			}
		}
		f, err := strconv.ParseFloat(s, 64)
		if math.IsInf(f, 0) {
			return nil, fmt.Errorf("floating-point number too large")
		}
		if err != nil {
			return nil, fmt.Errorf("invalid float literal: %s", s)
		}
		return Float(f), nil
	default:
		return nil, fmt.Errorf("float got %s, want number or string", x.Type())
	}
}

var (
	inf    = Float(math.Inf(+1))
	neginf = Float(math.Inf(-1))
	nan    = Float(math.NaN())
)

// https://github.com/google/starlark-go/blob/master/doc/spec.md#getattr
func getattr(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var object, dflt Value
	var name string
	if err := UnpackPositionalArgs("getattr", args, kwargs, 2, &object, &name, &dflt); err != nil {
		return nil, err
	}
	if object, ok := object.(HasAttrs); ok {
		v, err := object.Attr(name)
		if err != nil {
			// An error could mean the field doesn't exist,
			// or it exists but could not be computed.
			if dflt != nil {
				return dflt, nil
			}
			return nil, nameErr(b, err)
		}
		if v != nil {
			return v, nil
		}
		// (nil, nil) => no such field
	}
	if dflt != nil {
		return dflt, nil
	}
	return nil, fmt.Errorf("getattr: %s has no .%s field or method", object.Type(), name)
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#hasattr
func hasattr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var object Value
	var name string
	if err := UnpackPositionalArgs("hasattr", args, kwargs, 2, &object, &name); err != nil {
		return nil, err
	}
	if object, ok := object.(HasAttrs); ok {
		v, err := object.Attr(name)
		if err == nil {
			return Bool(v != nil), nil
		}

		// An error does not conclusively indicate presence or
		// absence of a field: it could occur while computing
		// the value of a present attribute, or it could be a
		// "no such attribute" error with details.
		for _, x := range object.AttrNames() {
			if x == name {
				return True, nil
			}
		}
	}
	return False, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#hash
func hash(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value
	if err := UnpackPositionalArgs("hash", args, kwargs, 1, &x); err != nil {
		return nil, err
	}

	var h int64
	switch x := x.(type) {
	case String:
		// The Starlark spec requires that the hash function be
		// deterministic across all runs, motivated by the need
		// for reproducibility of builds. Thus we cannot call
		// String.Hash, which uses the fastest implementation
		// available, because as varies across process restarts,
		// and may evolve with the implementation.
		h = int64(javaStringHash(string(x)))
	case Bytes:
		h = int64(softHashString(string(x))) // FNV32
	default:
		return nil, fmt.Errorf("hash: got %s, want string or bytes", x.Type())
	}
	return MakeInt64(h), nil
}

// javaStringHash returns the same hash as would be produced by
// java.lang.String.hashCode. This requires transcoding the string to
// UTF-16; transcoding may introduce Unicode replacement characters
// U+FFFD if s does not contain valid UTF-8.
func javaStringHash(s string) (h int32) {
	for _, r := range s {
		if utf16.IsSurrogate(r) {
			c1, c2 := utf16.EncodeRune(r)
			h = 31*h + c1
			h = 31*h + c2
		} else {
			h = 31*h + r // r may be U+FFFD
		}
	}
	return h
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#int
func int_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value = zero
	var base Value
	if err := UnpackArgs("int", args, kwargs, "x", &x, "base?", &base); err != nil {
		return nil, err
	}

	if s, ok := AsString(x); ok {
		b := 10
		if base != nil {
			var err error
			b, err = AsInt32(base)
			if err != nil {
				return nil, fmt.Errorf("int: for base, got %s, want int", base.Type())
			}
			if b != 0 && (b < 2 || b > 36) {
				return nil, fmt.Errorf("int: base must be an integer >= 2 && <= 36")
			}
		}
		res := parseInt(s, b)
		if res == nil {
			return nil, fmt.Errorf("int: invalid literal with base %d: %s", b, s)
		}
		return res, nil
	}

	if base != nil {
		return nil, fmt.Errorf("int: can't convert non-string with explicit base")
	}

	if b, ok := x.(Bool); ok {
		if b {
			return one, nil
		} else {
			return zero, nil
		}
	}

	i, err := NumberToInt(x)
	if err != nil {
		return nil, fmt.Errorf("int: %s", err)
	}
	return i, nil
}

// parseInt defines the behavior of int(string, base=int). It returns nil on error.
func parseInt(s string, base int) Value {
	// remove sign
	var neg bool
	if s != "" {
		if s[0] == '+' {
			s = s[1:]
		} else if s[0] == '-' {
			neg = true
			s = s[1:]
		}
	}

	// remove optional base prefix
	baseprefix := 0
	if len(s) > 1 && s[0] == '0' {
		if len(s) > 2 {
			switch s[1] {
			case 'o', 'O':
				baseprefix = 8
			case 'x', 'X':
				baseprefix = 16
			case 'b', 'B':
				baseprefix = 2
			}
		}
		if baseprefix != 0 {
			// Remove the base prefix if it matches
			// the explicit base, or if base=0.
			if base == 0 || baseprefix == base {
				base = baseprefix
				s = s[2:]
			}
		} else {
			// For automatic base detection,
			// a string starting with zero
			// must be all zeros.
			// Thus we reject int("0755", 0).
			if base == 0 {
				for i := 1; i < len(s); i++ {
					if s[i] != '0' {
						return nil
					}
				}
				return zero
			}
		}
	}
	if base == 0 {
		base = 10
	}

	// we explicitly handled sign above.
	// if a sign remains, it is invalid.
	if s != "" && (s[0] == '-' || s[0] == '+') {
		return nil
	}

	// s has no sign or base prefix.
	if i, ok := new(big.Int).SetString(s, base); ok {
		res := MakeBigInt(i)
		if neg {
			res = zero.Sub(res)
		}
		return res
	}

	return nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#len
func len_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value
	if err := UnpackPositionalArgs("len", args, kwargs, 1, &x); err != nil {
		return nil, err
	}
	len := Len(x)
	if len < 0 {
		return nil, fmt.Errorf("len: value of type %s has no len", x.Type())
	}
	return MakeInt(len), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list
func list(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("list", args, kwargs, 0, &iterable); err != nil {
		return nil, err
	}
	var elems []Value
	if iterable != nil {
		iter := iterable.Iterate()
		defer iter.Done()
		if n := Len(iterable); n > 0 {
			elems = make([]Value, 0, n) // preallocate if length known
		}
		var x Value
		for iter.Next(&x) {
			elems = append(elems, x)
		}
	}
	return NewList(elems), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#min
func minmax(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(args) == 0 {
		return nil, fmt.Errorf("%s requires at least one positional argument", b.Name())
	}
	var keyFunc Callable
	if err := UnpackArgs(b.Name(), nil, kwargs, "key?", &keyFunc); err != nil {
		return nil, err
	}
	var op syntax.Token
	if b.Name() == "max" {
		op = syntax.GT
	} else {
		op = syntax.LT
	}
	var iterable Value
	if len(args) == 1 {
		iterable = args[0]
	} else {
		iterable = args
	}
	iter := Iterate(iterable)
	if iter == nil {
		return nil, fmt.Errorf("%s: %s value is not iterable", b.Name(), iterable.Type())
	}
	defer iter.Done()
	var extremum Value
	if !iter.Next(&extremum) {
		return nil, nameErr(b, "argument is an empty sequence")
	}

	var extremeKey Value
	var keyargs Tuple
	if keyFunc == nil {
		extremeKey = extremum
	} else {
		keyargs = Tuple{extremum}
		res, err := Call(thread, keyFunc, keyargs, nil)
		if err != nil {
			return nil, err // to preserve backtrace, don't modify error
		}
		extremeKey = res
	}

	var x Value
	for iter.Next(&x) {
		var key Value
		if keyFunc == nil {
			key = x
		} else {
			keyargs[0] = x
			res, err := Call(thread, keyFunc, keyargs, nil)
			if err != nil {
				return nil, err // to preserve backtrace, don't modify error
			}
			key = res
		}

		if ok, err := Compare(op, key, extremeKey); err != nil {
			return nil, nameErr(b, err)
		} else if ok {
			extremum = x
			extremeKey = key
		}
	}
	return extremum, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#ord
func ord(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("ord does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("ord: got %d arguments, want 1", len(args))
	}
	switch x := args[0].(type) {
	case String:
		// ord(string) returns int value of sole rune.
		s := string(x)
		r, sz := utf8.DecodeRuneInString(s)
		if sz == 0 || sz != len(s) {
			n := utf8.RuneCountInString(s)
			return nil, fmt.Errorf("ord: string encodes %d Unicode code points, want 1", n)
		}
		return MakeInt(int(r)), nil

	case Bytes:
		// ord(bytes) returns int value of sole byte.
		if len(x) != 1 {
			return nil, fmt.Errorf("ord: bytes has length %d, want 1", len(x))
		}
		return MakeInt(int(x[0])), nil
	default:
		return nil, fmt.Errorf("ord: got %s, want string or bytes", x.Type())
	}
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#print
func print(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	sep := " "
	if err := UnpackArgs("print", nil, kwargs, "sep?", &sep); err != nil {
		return nil, err
	}
	buf := new(strings.Builder)
	for i, v := range args {
		if i > 0 {
			buf.WriteString(sep)
		}
		if s, ok := AsString(v); ok {
			buf.WriteString(s)
		} else if b, ok := v.(Bytes); ok {
			buf.WriteString(string(b))
		} else {
			writeValue(buf, v, nil)
		}
	}

	s := buf.String()
	if thread.Print != nil {
		thread.Print(thread, s)
	} else {
		fmt.Fprintln(os.Stderr, s)
	}
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#range
func range_(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var start, stop, step int
	step = 1
	if err := UnpackPositionalArgs("range", args, kwargs, 1, &start, &stop, &step); err != nil {
		return nil, err
	}

	if len(args) == 1 {
		// range(stop)
		start, stop = 0, start
	}
	if step == 0 {
		// we were given range(start, stop, 0)
		return nil, nameErr(b, "step argument must not be zero")
	}

	return rangeValue{start: start, stop: stop, step: step, len: rangeLen(start, stop, step)}, nil
}

// A rangeValue is a comparable, immutable, indexable sequence of integers
// defined by the three parameters to a range(...) call.
// Invariant: step != 0.
type rangeValue struct{ start, stop, step, len int }

var (
	_ Indexable  = rangeValue{}
	_ Sequence   = rangeValue{}
	_ Comparable = rangeValue{}
	_ Sliceable  = rangeValue{}
)

func (r rangeValue) Len() int          { return r.len }
func (r rangeValue) Index(i int) Value { return MakeInt(r.start + i*r.step) }
func (r rangeValue) Iterate() Iterator { return &rangeIterator{r, 0} }

// rangeLen calculates the length of a range with the provided start, stop, and step.
// caller must ensure that step is non-zero.
func rangeLen(start, stop, step int) int {
	switch {
	case step > 0:
		if stop > start {
			return (stop-1-start)/step + 1
		}
	case step < 0:
		if start > stop {
			return (start-1-stop)/-step + 1
		}
	default:
		panic("rangeLen: zero step")
	}
	return 0
}

func (r rangeValue) Slice(start, end, step int) Value {
	newStart := r.start + r.step*start
	newStop := r.start + r.step*end
	newStep := r.step * step
	return rangeValue{
		start: newStart,
		stop:  newStop,
		step:  newStep,
		len:   rangeLen(newStart, newStop, newStep),
	}
}

func (r rangeValue) Freeze() {} // immutable
func (r rangeValue) String() string {
	if r.step != 1 {
		return fmt.Sprintf("range(%d, %d, %d)", r.start, r.stop, r.step)
	} else if r.start != 0 {
		return fmt.Sprintf("range(%d, %d)", r.start, r.stop)
	} else {
		return fmt.Sprintf("range(%d)", r.stop)
	}
}
func (r rangeValue) Type() string          { return "range" }
func (r rangeValue) Truth() Bool           { return r.len > 0 }
func (r rangeValue) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: range") }

func (x rangeValue) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {
	y := y_.(rangeValue)
	switch op {
	case syntax.EQL:
		return rangeEqual(x, y), nil
	case syntax.NEQ:
		return !rangeEqual(x, y), nil
	default:
		return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
	}
}

func rangeEqual(x, y rangeValue) bool {
	// Two ranges compare equal if they denote the same sequence.
	if x.len != y.len {
		return false // sequences differ in length
	}
	if x.len == 0 {
		return true // both sequences are empty
	}
	if x.start != y.start {
		return false // first element differs
	}
	return x.len == 1 || x.step == y.step
}

func (r rangeValue) contains(x Int) bool {
	x32, err := AsInt32(x)
	if err != nil {
		return false // out of range
	}
	delta := x32 - r.start
	quo, rem := delta/r.step, delta%r.step
	return rem == 0 && 0 <= quo && quo < r.len
}

type rangeIterator struct {
	r rangeValue
	i int
}

func (it *rangeIterator) Next(p *Value) bool {
	if it.i < it.r.len {
		*p = it.r.Index(it.i)
		it.i++
		return true
	}
	return false
}
func (*rangeIterator) Done() {}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#repr
func repr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value
	if err := UnpackPositionalArgs("repr", args, kwargs, 1, &x); err != nil {
		return nil, err
	}
	return String(x.String()), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#reversed
func reversed(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("reversed", args, kwargs, 1, &iterable); err != nil {
		return nil, err
	}
	iter := iterable.Iterate()
	defer iter.Done()
	var elems []Value
	if n := Len(args[0]); n >= 0 {
		elems = make([]Value, 0, n) // preallocate if length known
	}
	var x Value
	for iter.Next(&x) {
		elems = append(elems, x)
	}
	n := len(elems)
	for i := 0; i < n>>1; i++ {
		elems[i], elems[n-1-i] = elems[n-1-i], elems[i]
	}
	return NewList(elems), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#set
func set(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("set", args, kwargs, 0, &iterable); err != nil {
		return nil, err
	}
	set := new(Set)
	if iterable != nil {
		iter := iterable.Iterate()
		defer iter.Done()
		var x Value
		for iter.Next(&x) {
			if err := set.Insert(x); err != nil {
				return nil, nameErr(b, err)
			}
		}
	}
	return set, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#sorted
func sorted(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	// Oddly, Python's sorted permits all arguments to be positional, thus so do we.
	var iterable Iterable
	var key Callable
	var reverse bool
	if err := UnpackArgs("sorted", args, kwargs,
		"iterable", &iterable,
		"key?", &key,
		"reverse?", &reverse,
	); err != nil {
		return nil, err
	}

	iter := iterable.Iterate()
	defer iter.Done()
	var values []Value
	if n := Len(iterable); n > 0 {
		values = make(Tuple, 0, n) // preallocate if length is known
	}
	var x Value
	for iter.Next(&x) {
		values = append(values, x)
	}

	// Derive keys from values by applying key function.
	var keys []Value
	if key != nil {
		keys = make([]Value, len(values))
		for i, v := range values {
			k, err := Call(thread, key, Tuple{v}, nil)
			if err != nil {
				return nil, err // to preserve backtrace, don't modify error
			}
			keys[i] = k
		}
	}

	slice := &sortSlice{keys: keys, values: values}
	if reverse {
		sort.Stable(sort.Reverse(slice))
	} else {
		sort.Stable(slice)
	}
	return NewList(slice.values), slice.err
}

type sortSlice struct {
	keys   []Value // nil => values[i] is key
	values []Value
	err    error
}

func (s *sortSlice) Len() int { return len(s.values) }
func (s *sortSlice) Less(i, j int) bool {
	keys := s.keys
	if s.keys == nil {
		keys = s.values
	}
	ok, err := Compare(syntax.LT, keys[i], keys[j])
	if err != nil {
		s.err = err
	}
	return ok
}
func (s *sortSlice) Swap(i, j int) {
	if s.keys != nil {
		s.keys[i], s.keys[j] = s.keys[j], s.keys[i]
	}
	s.values[i], s.values[j] = s.values[j], s.values[i]
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#str
func str(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("str does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("str: got %d arguments, want exactly 1", len(args))
	}
	switch x := args[0].(type) {
	case String:
		return x, nil
	case Bytes:
		// Invalid encodings are replaced by that of U+FFFD.
		return String(utf8Transcode(string(x))), nil
	default:
		return String(x.String()), nil
	}
}

// utf8Transcode returns the UTF-8-to-UTF-8 transcoding of s.
// The effect is that each code unit that is part of an
// invalid sequence is replaced by U+FFFD.
func utf8Transcode(s string) string {
	if utf8.ValidString(s) {
		return s
	}
	var out strings.Builder
	for _, r := range s {
		out.WriteRune(r)
	}
	return out.String()
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#tuple
func tuple(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs("tuple", args, kwargs, 0, &iterable); err != nil {
		return nil, err
	}
	if len(args) == 0 {
		return Tuple(nil), nil
	}
	iter := iterable.Iterate()
	defer iter.Done()
	var elems Tuple
	if n := Len(iterable); n > 0 {
		elems = make(Tuple, 0, n) // preallocate if length is known
	}
	var x Value
	for iter.Next(&x) {
		elems = append(elems, x)
	}
	return elems, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#type
func type_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("type does not accept keyword arguments")
	}
	if len(args) != 1 {
		return nil, fmt.Errorf("type: got %d arguments, want exactly 1", len(args))
	}
	return String(args[0].Type()), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#zip
func zip(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(kwargs) > 0 {
		return nil, fmt.Errorf("zip does not accept keyword arguments")
	}
	rows, cols := 0, len(args)
	iters := make([]Iterator, cols)
	defer func() {
		for _, iter := range iters {
			if iter != nil {
				iter.Done()
			}
		}
	}()
	for i, seq := range args {
		it := Iterate(seq)
		if it == nil {
			return nil, fmt.Errorf("zip: argument #%d is not iterable: %s", i+1, seq.Type())
		}
		iters[i] = it
		n := Len(seq)
		if i == 0 || n < rows {
			rows = n // possibly -1
		}
	}
	var result []Value
	if rows >= 0 {
		// length known
		result = make([]Value, rows)
		array := make(Tuple, cols*rows) // allocate a single backing array
		for i := 0; i < rows; i++ {
			tuple := array[:cols:cols]
			array = array[cols:]
			for j, iter := range iters {
				iter.Next(&tuple[j])
			}
			result[i] = tuple
		}
	} else {
		// length not known
	outer:
		for {
			tuple := make(Tuple, cols)
			for i, iter := range iters {
				if !iter.Next(&tuple[i]) {
					break outer
				}
			}
			result = append(result, tuple)
		}
	}
	return NewList(result), nil
}

// ---- methods of built-in types ---

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·get
func dict_get(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var key, dflt Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &key, &dflt); err != nil {
		return nil, err
	}
	if v, ok, err := b.Receiver().(*Dict).Get(key); err != nil {
		return nil, nameErr(b, err)
	} else if ok {
		return v, nil
	} else if dflt != nil {
		return dflt, nil
	}
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·clear
func dict_clear(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	return None, b.Receiver().(*Dict).Clear()
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·items
func dict_items(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	items := b.Receiver().(*Dict).Items()
	res := make([]Value, len(items))
	for i, item := range items {
		res[i] = item // convert [2]Value to Value
	}
	return NewList(res), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·keys
func dict_keys(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	return NewList(b.Receiver().(*Dict).Keys()), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·pop
func dict_pop(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var k, d Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &k, &d); err != nil {
		return nil, err
	}
	if v, found, err := b.Receiver().(*Dict).Delete(k); err != nil {
		return nil, nameErr(b, err) // dict is frozen or key is unhashable
	} else if found {
		return v, nil
	} else if d != nil {
		return d, nil
	}
	return nil, nameErr(b, "missing key")
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·popitem
func dict_popitem(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := b.Receiver().(*Dict)
	k, ok := recv.ht.first()
	if !ok {
		return nil, nameErr(b, "empty dict")
	}
	v, _, err := recv.Delete(k)
	if err != nil {
		return nil, nameErr(b, err) // dict is frozen
	}
	return Tuple{k, v}, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·setdefault
func dict_setdefault(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var key, dflt Value = nil, None
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &key, &dflt); err != nil {
		return nil, err
	}
	dict := b.Receiver().(*Dict)
	if v, ok, err := dict.Get(key); err != nil {
		return nil, nameErr(b, err)
	} else if ok {
		return v, nil
	} else if err := dict.SetKey(key, dflt); err != nil {
		return nil, nameErr(b, err)
	} else {
		return dflt, nil
	}
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·update
func dict_update(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if len(args) > 1 {
		return nil, fmt.Errorf("update: got %d arguments, want at most 1", len(args))
	}
	if err := updateDict(b.Receiver().(*Dict), args, kwargs); err != nil {
		return nil, fmt.Errorf("update: %v", err)
	}
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·update
func dict_values(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	items := b.Receiver().(*Dict).Items()
	res := make([]Value, len(items))
	for i, item := range items {
		res[i] = item[1]
	}
	return NewList(res), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·append
func list_append(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var object Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &object); err != nil {
		return nil, err
	}
	recv := b.Receiver().(*List)
	if err := recv.checkMutable("append to"); err != nil {
		return nil, nameErr(b, err)
	}
	recv.elems = append(recv.elems, object)
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·clear
func list_clear(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	if err := b.Receiver().(*List).Clear(); err != nil {
		return nil, nameErr(b, err)
	}
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·extend
func list_extend(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := b.Receiver().(*List)
	var iterable Iterable
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &iterable); err != nil {
		return nil, err
	}
	if err := recv.checkMutable("extend"); err != nil {
		return nil, nameErr(b, err)
	}
	listExtend(recv, iterable)
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·index
func list_index(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var value, start_, end_ Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &value, &start_, &end_); err != nil {
		return nil, err
	}

	recv := b.Receiver().(*List)
	start, end, err := indices(start_, end_, recv.Len())
	if err != nil {
		return nil, nameErr(b, err)
	}

	for i := start; i < end; i++ {
		if eq, err := Equal(recv.elems[i], value); err != nil {
			return nil, nameErr(b, err)
		} else if eq {
			return MakeInt(i), nil
		}
	}
	return nil, nameErr(b, "value not in list")
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·insert
func list_insert(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := b.Receiver().(*List)
	var index int
	var object Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 2, &index, &object); err != nil {
		return nil, err
	}
	if err := recv.checkMutable("insert into"); err != nil {
		return nil, nameErr(b, err)
	}

	if index < 0 {
		index += recv.Len()
	}

	if index >= recv.Len() {
		// end
		recv.elems = append(recv.elems, object)
	} else {
		if index < 0 {
			index = 0 // start
		}
		recv.elems = append(recv.elems, nil)
		copy(recv.elems[index+1:], recv.elems[index:]) // slide up one
		recv.elems[index] = object
	}
	return None, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·remove
func list_remove(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := b.Receiver().(*List)
	var value Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &value); err != nil {
		return nil, err
	}
	if err := recv.checkMutable("remove from"); err != nil {
		return nil, nameErr(b, err)
	}
	for i, elem := range recv.elems {
		if eq, err := Equal(elem, value); err != nil {
			return nil, fmt.Errorf("remove: %v", err)
		} else if eq {
			recv.elems = append(recv.elems[:i], recv.elems[i+1:]...)
			return None, nil
		}
	}
	return nil, fmt.Errorf("remove: element not found")
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·pop
func list_pop(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := b.Receiver()
	list := recv.(*List)
	n := list.Len()
	i := n - 1
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &i); err != nil {
		return nil, err
	}
	origI := i
	if i < 0 {
		i += n
	}
	if i < 0 || i >= n {
		return nil, nameErr(b, outOfRange(origI, n, list))
	}
	if err := list.checkMutable("pop from"); err != nil {
		return nil, nameErr(b, err)
	}
	res := list.elems[i]
	list.elems = append(list.elems[:i], list.elems[i+1:]...)
	return res, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·capitalize
func string_capitalize(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	s := string(b.Receiver().(String))
	res := new(strings.Builder)
	res.Grow(len(s))
	for i, r := range s {
		if i == 0 {
			r = unicode.ToTitle(r)
		} else {
			r = unicode.ToLower(r)
		}
		res.WriteRune(r)
	}
	return String(res.String()), nil
}

// string_iterable returns an unspecified iterable value whose iterator yields:
// - elems: successive 1-byte substrings
// - codepoints: successive substrings that encode a single Unicode code point.
// - elem_ords: numeric values of successive bytes
// - codepoint_ords: numeric values of successive Unicode code points
func string_iterable(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	s := b.Receiver().(String)
	ords := b.Name()[len(b.Name())-2] == 'd'
	codepoints := b.Name()[0] == 'c'
	if codepoints {
		return stringCodepoints{s, ords}, nil
	} else {
		return stringElems{s, ords}, nil
	}
}

// bytes_elems returns an unspecified iterable value whose
// iterator yields the int values of successive elements.
func bytes_elems(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	return bytesIterable{b.Receiver().(Bytes)}, nil
}

// A bytesIterable is an iterable returned by bytes.elems(),
// whose iterator yields a sequence of numeric bytes values.
type bytesIterable struct{ bytes Bytes }

var _ Iterable = (*bytesIterable)(nil)

func (bi bytesIterable) String() string        { return bi.bytes.String() + ".elems()" }
func (bi bytesIterable) Type() string          { return "bytes.elems" }
func (bi bytesIterable) Freeze()               {} // immutable
func (bi bytesIterable) Truth() Bool           { return True }
func (bi bytesIterable) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", bi.Type()) }
func (bi bytesIterable) Iterate() Iterator     { return &bytesIterator{bi.bytes} }

type bytesIterator struct{ bytes Bytes }

func (it *bytesIterator) Next(p *Value) bool {
	if it.bytes == "" {
		return false
	}
	*p = MakeInt(int(it.bytes[0]))
	it.bytes = it.bytes[1:]
	return true
}

func (*bytesIterator) Done() {}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·count
func string_count(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var sub string
	var start_, end_ Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sub, &start_, &end_); err != nil {
		return nil, err
	}

	recv := string(b.Receiver().(String))
	start, end, err := indices(start_, end_, len(recv))
	if err != nil {
		return nil, nameErr(b, err)
	}

	var slice string
	if start < end {
		slice = recv[start:end]
	}
	return MakeInt(strings.Count(slice, sub)), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isalnum
func string_isalnum(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	for _, r := range recv {
		if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
			return False, nil
		}
	}
	return Bool(recv != ""), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isalpha
func string_isalpha(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	for _, r := range recv {
		if !unicode.IsLetter(r) {
			return False, nil
		}
	}
	return Bool(recv != ""), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isdigit
func string_isdigit(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	for _, r := range recv {
		if !unicode.IsDigit(r) {
			return False, nil
		}
	}
	return Bool(recv != ""), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·islower
func string_islower(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	return Bool(isCasedString(recv) && recv == strings.ToLower(recv)), nil
}

// isCasedString reports whether its argument contains any cased code points.
func isCasedString(s string) bool {
	for _, r := range s {
		if isCasedRune(r) {
			return true
		}
	}
	return false
}

func isCasedRune(r rune) bool {
	// It's unclear what the correct behavior is for a rune such as 'ffi',
	// a lowercase letter with no upper or title case and no SimpleFold.
	return 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || unicode.SimpleFold(r) != r
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isspace
func string_isspace(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	for _, r := range recv {
		if !unicode.IsSpace(r) {
			return False, nil
		}
	}
	return Bool(recv != ""), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·istitle
func string_istitle(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))

	// Python semantics differ from x==strings.{To,}Title(x) in Go:
	// "uppercase characters may only follow uncased characters and
	// lowercase characters only cased ones."
	var cased, prevCased bool
	for _, r := range recv {
		if 'A' <= r && r <= 'Z' || unicode.IsTitle(r) { // e.g. "Dž"
			if prevCased {
				return False, nil
			}
			prevCased = true
			cased = true
		} else if unicode.IsLower(r) {
			if !prevCased {
				return False, nil
			}
			prevCased = true
			cased = true
		} else if unicode.IsUpper(r) {
			return False, nil
		} else {
			prevCased = false
		}
	}
	return Bool(cased), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isupper
func string_isupper(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	return Bool(isCasedString(recv) && recv == strings.ToUpper(recv)), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·find
func string_find(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	return string_find_impl(b, args, kwargs, true, false)
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·format
func string_format(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	format := string(b.Receiver().(String))
	var auto, manual bool // kinds of positional indexing used
	buf := new(strings.Builder)
	index := 0
	for {
		literal := format
		i := strings.IndexByte(format, '{')
		if i >= 0 {
			literal = format[:i]
		}

		// Replace "}}" with "}" in non-field portion, rejecting a lone '}'.
		for {
			j := strings.IndexByte(literal, '}')
			if j < 0 {
				buf.WriteString(literal)
				break
			}
			if len(literal) == j+1 || literal[j+1] != '}' {
				return nil, fmt.Errorf("format: single '}' in format")
			}
			buf.WriteString(literal[:j+1])
			literal = literal[j+2:]
		}

		if i < 0 {
			break // end of format string
		}

		if i+1 < len(format) && format[i+1] == '{' {
			// "{{" means a literal '{'
			buf.WriteByte('{')
			format = format[i+2:]
			continue
		}

		format = format[i+1:]
		i = strings.IndexByte(format, '}')
		if i < 0 {
			return nil, fmt.Errorf("format: unmatched '{' in format")
		}

		var arg Value
		conv := "s"
		var spec string

		field := format[:i]
		format = format[i+1:]

		var name string
		if i := strings.IndexByte(field, '!'); i < 0 {
			// "name" or "name:spec"
			if i := strings.IndexByte(field, ':'); i < 0 {
				name = field
			} else {
				name = field[:i]
				spec = field[i+1:]
			}
		} else {
			// "name!conv" or "name!conv:spec"
			name = field[:i]
			field = field[i+1:]
			// "conv" or "conv:spec"
			if i := strings.IndexByte(field, ':'); i < 0 {
				conv = field
			} else {
				conv = field[:i]
				spec = field[i+1:]
			}
		}

		if name == "" {
			// "{}": automatic indexing
			if manual {
				return nil, fmt.Errorf("format: cannot switch from manual field specification to automatic field numbering")
			}
			auto = true
			if index >= len(args) {
				return nil, fmt.Errorf("format: tuple index out of range")
			}
			arg = args[index]
			index++
		} else if num, ok := decimal(name); ok {
			// positional argument
			if auto {
				return nil, fmt.Errorf("format: cannot switch from automatic field numbering to manual field specification")
			}
			manual = true
			if num >= len(args) {
				return nil, fmt.Errorf("format: tuple index out of range")
			} else {
				arg = args[num]
			}
		} else {
			// keyword argument
			for _, kv := range kwargs {
				if string(kv[0].(String)) == name {
					arg = kv[1]
					break
				}
			}
			if arg == nil {
				// Starlark does not support Python's x.y or a[i] syntaxes,
				// or nested use of {...}.
				if strings.Contains(name, ".") {
					return nil, fmt.Errorf("format: attribute syntax x.y is not supported in replacement fields: %s", name)
				}
				if strings.Contains(name, "[") {
					return nil, fmt.Errorf("format: element syntax a[i] is not supported in replacement fields: %s", name)
				}
				if strings.Contains(name, "{") {
					return nil, fmt.Errorf("format: nested replacement fields not supported")
				}
				return nil, fmt.Errorf("format: keyword %s not found", name)
			}
		}

		if spec != "" {
			// Starlark does not support Python's format_spec features.
			return nil, fmt.Errorf("format spec features not supported in replacement fields: %s", spec)
		}

		switch conv {
		case "s":
			if str, ok := AsString(arg); ok {
				buf.WriteString(str)
			} else {
				writeValue(buf, arg, nil)
			}
		case "r":
			writeValue(buf, arg, nil)
		default:
			return nil, fmt.Errorf("format: unknown conversion %q", conv)
		}
	}
	return String(buf.String()), nil
}

// decimal interprets s as a sequence of decimal digits.
func decimal(s string) (x int, ok bool) {
	n := len(s)
	for i := 0; i < n; i++ {
		digit := s[i] - '0'
		if digit > 9 {
			return 0, false
		}
		x = x*10 + int(digit)
		if x < 0 {
			return 0, false // underflow
		}
	}
	return x, true
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·index
func string_index(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	return string_find_impl(b, args, kwargs, false, false)
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·join
func string_join(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := string(b.Receiver().(String))
	var iterable Iterable
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &iterable); err != nil {
		return nil, err
	}
	iter := iterable.Iterate()
	defer iter.Done()
	buf := new(strings.Builder)
	var x Value
	for i := 0; iter.Next(&x); i++ {
		if i > 0 {
			buf.WriteString(recv)
		}
		s, ok := AsString(x)
		if !ok {
			return nil, fmt.Errorf("join: in list, want string, got %s", x.Type())
		}
		buf.WriteString(s)
	}
	return String(buf.String()), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·lower
func string_lower(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	return String(strings.ToLower(string(b.Receiver().(String)))), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·partition
func string_partition(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := string(b.Receiver().(String))
	var sep string
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sep); err != nil {
		return nil, err
	}
	if sep == "" {
		return nil, nameErr(b, "empty separator")
	}
	var i int
	if b.Name()[0] == 'p' {
		i = strings.Index(recv, sep) // partition
	} else {
		i = strings.LastIndex(recv, sep) // rpartition
	}
	tuple := make(Tuple, 0, 3)
	if i < 0 {
		if b.Name()[0] == 'p' {
			tuple = append(tuple, String(recv), String(""), String(""))
		} else {
			tuple = append(tuple, String(""), String(""), String(recv))
		}
	} else {
		tuple = append(tuple, String(recv[:i]), String(sep), String(recv[i+len(sep):]))
	}
	return tuple, nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·replace
func string_replace(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := string(b.Receiver().(String))
	var old, new string
	count := -1
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 2, &old, &new, &count); err != nil {
		return nil, err
	}
	return String(strings.Replace(recv, old, new, count)), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rfind
func string_rfind(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	return string_find_impl(b, args, kwargs, true, true)
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rindex
func string_rindex(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	return string_find_impl(b, args, kwargs, false, true)
}

// https://github.com/google/starlark-go/starlark/blob/master/doc/spec.md#string·startswith
// https://github.com/google/starlark-go/starlark/blob/master/doc/spec.md#string·endswith
func string_startswith(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var x Value
	var start, end Value = None, None
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &x, &start, &end); err != nil {
		return nil, err
	}

	// compute effective substring.
	s := string(b.Receiver().(String))
	if start, end, err := indices(start, end, len(s)); err != nil {
		return nil, nameErr(b, err)
	} else {
		if end < start {
			end = start // => empty result
		}
		s = s[start:end]
	}

	f := strings.HasPrefix
	if b.Name()[0] == 'e' { // endswith
		f = strings.HasSuffix
	}

	switch x := x.(type) {
	case Tuple:
		for i, x := range x {
			prefix, ok := AsString(x)
			if !ok {
				return nil, fmt.Errorf("%s: want string, got %s, for element %d",
					b.Name(), x.Type(), i)
			}
			if f(s, prefix) {
				return True, nil
			}
		}
		return False, nil
	case String:
		return Bool(f(s, string(x))), nil
	}
	return nil, fmt.Errorf("%s: got %s, want string or tuple of string", b.Name(), x.Type())
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·strip
// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·lstrip
// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rstrip
func string_strip(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var chars string
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &chars); err != nil {
		return nil, err
	}
	recv := string(b.Receiver().(String))
	var s string
	switch b.Name()[0] {
	case 's': // strip
		if chars != "" {
			s = strings.Trim(recv, chars)
		} else {
			s = strings.TrimSpace(recv)
		}
	case 'l': // lstrip
		if chars != "" {
			s = strings.TrimLeft(recv, chars)
		} else {
			s = strings.TrimLeftFunc(recv, unicode.IsSpace)
		}
	case 'r': // rstrip
		if chars != "" {
			s = strings.TrimRight(recv, chars)
		} else {
			s = strings.TrimRightFunc(recv, unicode.IsSpace)
		}
	}
	return String(s), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·title
func string_title(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}

	s := string(b.Receiver().(String))

	// Python semantics differ from x==strings.{To,}Title(x) in Go:
	// "uppercase characters may only follow uncased characters and
	// lowercase characters only cased ones."
	buf := new(strings.Builder)
	buf.Grow(len(s))
	var prevCased bool
	for _, r := range s {
		if prevCased {
			r = unicode.ToLower(r)
		} else {
			r = unicode.ToTitle(r)
		}
		prevCased = isCasedRune(r)
		buf.WriteRune(r)
	}
	return String(buf.String()), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·upper
func string_upper(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {
		return nil, err
	}
	return String(strings.ToUpper(string(b.Receiver().(String)))), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·split
// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rsplit
func string_split(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	recv := string(b.Receiver().(String))
	var sep_ Value
	maxsplit := -1
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &sep_, &maxsplit); err != nil {
		return nil, err
	}

	var res []string

	if sep_ == nil || sep_ == None {
		// special case: split on whitespace
		if maxsplit < 0 {
			res = strings.Fields(recv)
		} else if b.Name() == "split" {
			res = splitspace(recv, maxsplit)
		} else { // rsplit
			res = rsplitspace(recv, maxsplit)
		}

	} else if sep, ok := AsString(sep_); ok {
		if sep == "" {
			return nil, fmt.Errorf("split: empty separator")
		}
		// usual case: split on non-empty separator
		if maxsplit < 0 {
			res = strings.Split(recv, sep)
		} else if b.Name() == "split" {
			res = strings.SplitN(recv, sep, maxsplit+1)
		} else { // rsplit
			res = strings.Split(recv, sep)
			if excess := len(res) - maxsplit; excess > 0 {
				res[0] = strings.Join(res[:excess], sep)
				res = append(res[:1], res[excess:]...)
			}
		}

	} else {
		return nil, fmt.Errorf("split: got %s for separator, want string", sep_.Type())
	}

	list := make([]Value, len(res))
	for i, x := range res {
		list[i] = String(x)
	}
	return NewList(list), nil
}

// Precondition: max >= 0.
func rsplitspace(s string, max int) []string {
	res := make([]string, 0, max+1)
	end := -1 // index of field end, or -1 in a region of spaces.
	for i := len(s); i > 0; {
		r, sz := utf8.DecodeLastRuneInString(s[:i])
		if unicode.IsSpace(r) {
			if end >= 0 {
				if len(res) == max {
					break // let this field run to the start
				}
				res = append(res, s[i:end])
				end = -1
			}
		} else if end < 0 {
			end = i
		}
		i -= sz
	}
	if end >= 0 {
		res = append(res, s[:end])
	}

	resLen := len(res)
	for i := 0; i < resLen/2; i++ {
		res[i], res[resLen-1-i] = res[resLen-1-i], res[i]
	}

	return res
}

// Precondition: max >= 0.
func splitspace(s string, max int) []string {
	var res []string
	start := -1 // index of field start, or -1 in a region of spaces
	for i, r := range s {
		if unicode.IsSpace(r) {
			if start >= 0 {
				if len(res) == max {
					break // let this field run to the end
				}
				res = append(res, s[start:i])
				start = -1
			}
		} else if start == -1 {
			start = i
		}
	}
	if start >= 0 {
		res = append(res, s[start:])
	}
	return res
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·splitlines
func string_splitlines(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var keepends bool
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &keepends); err != nil {
		return nil, err
	}
	var lines []string
	if s := string(b.Receiver().(String)); s != "" {
		// TODO(adonovan): handle CRLF correctly.
		if keepends {
			lines = strings.SplitAfter(s, "\n")
		} else {
			lines = strings.Split(s, "\n")
		}
		if strings.HasSuffix(s, "\n") {
			lines = lines[:len(lines)-1]
		}
	}
	list := make([]Value, len(lines))
	for i, x := range lines {
		list[i] = String(x)
	}
	return NewList(list), nil
}

// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·union.
func set_union(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
	var iterable Iterable
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &iterable); err != nil {
		return nil, err
	}
	iter := iterable.Iterate()
	defer iter.Done()
	union, err := b.Receiver().(*Set).Union(iter)
	if err != nil {
		return nil, nameErr(b, err)
	}
	return union, nil
}

// Common implementation of string_{r}{find,index}.
func string_find_impl(b *Builtin, args Tuple, kwargs []Tuple, allowError, last bool) (Value, error) {
	var sub string
	var start_, end_ Value
	if err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sub, &start_, &end_); err != nil {
		return nil, err
	}

	s := string(b.Receiver().(String))
	start, end, err := indices(start_, end_, len(s))
	if err != nil {
		return nil, nameErr(b, err)
	}
	var slice string
	if start < end {
		slice = s[start:end]
	}

	var i int
	if last {
		i = strings.LastIndex(slice, sub)
	} else {
		i = strings.Index(slice, sub)
	}
	if i < 0 {
		if !allowError {
			return nil, nameErr(b, "substring not found")
		}
		return MakeInt(-1), nil
	}
	return MakeInt(i + start), nil
}

// Common implementation of builtin dict function and dict.update method.
// Precondition: len(updates) == 0 or 1.
func updateDict(dict *Dict, updates Tuple, kwargs []Tuple) error {
	if len(updates) == 1 {
		switch updates := updates[0].(type) {
		case IterableMapping:
			// Iterate over dict's key/value pairs, not just keys.
			for _, item := range updates.Items() {
				if err := dict.SetKey(item[0], item[1]); err != nil {
					return err // dict is frozen
				}
			}
		default:
			// all other sequences
			iter := Iterate(updates)
			if iter == nil {
				return fmt.Errorf("got %s, want iterable", updates.Type())
			}
			defer iter.Done()
			var pair Value
			for i := 0; iter.Next(&pair); i++ {
				iter2 := Iterate(pair)
				if iter2 == nil {
					return fmt.Errorf("dictionary update sequence element #%d is not iterable (%s)", i, pair.Type())

				}
				defer iter2.Done()
				len := Len(pair)
				if len < 0 {
					return fmt.Errorf("dictionary update sequence element #%d has unknown length (%s)", i, pair.Type())
				} else if len != 2 {
					return fmt.Errorf("dictionary update sequence element #%d has length %d, want 2", i, len)
				}
				var k, v Value
				iter2.Next(&k)
				iter2.Next(&v)
				if err := dict.SetKey(k, v); err != nil {
					return err
				}
			}
		}
	}

	// Then add the kwargs.
	before := dict.Len()
	for _, pair := range kwargs {
		if err := dict.SetKey(pair[0], pair[1]); err != nil {
			return err // dict is frozen
		}
	}
	// In the common case, each kwarg will add another dict entry.
	// If that's not so, check whether it is because there was a duplicate kwarg.
	if dict.Len() < before+len(kwargs) {
		keys := make(map[String]bool, len(kwargs))
		for _, kv := range kwargs {
			k := kv[0].(String)
			if keys[k] {
				return fmt.Errorf("duplicate keyword arg: %v", k)
			}
			keys[k] = true
		}
	}

	return nil
}

// nameErr returns an error message of the form "name: msg"
// where name is b.Name() and msg is a string or error.
func nameErr(b *Builtin, msg interface{}) error {
	return fmt.Errorf("%s: %v", b.Name(), msg)
}

redpajama_set_name: RedPajamaGithub


text:
require './test/lib_read_write.rb'

class TestKgioPipe < Test::Unit::TestCase
  def setup
    @rd, @wr = Kgio::Pipe.new
  end

  include LibReadWriteTest
end


text:
{% load url from future %}

    <form id="form-{{ request.GET.dialog }}"
	  action='{% url "crits.backdoors.views.add_backdoor" %}'
	  method='POST' enctype="multipart/form-data"
      item-type="backdoor">

{{ backdoor_add.as_table }}

    </form>


text:
namespace fileapi {

namespace {

}  // namespace

FileSystemURL::FileSystemURL()
    : is_valid_(false),
      mount_type_(kFileSystemTypeUnknown),
      type_(kFileSystemTypeUnknown),
      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
}

// static
FileSystemURL FileSystemURL::CreateForTest(const GURL& url) {
  return FileSystemURL(url);
}

FileSystemURL FileSystemURL::CreateForTest(const GURL& origin,
                                           FileSystemType mount_type,
                                           const base::FilePath& virtual_path) {
  return FileSystemURL(origin, mount_type, virtual_path);
}

// static
bool FileSystemURL::ParseFileSystemSchemeURL(
    const GURL& url,
    GURL* origin_url,
    FileSystemType* mount_type,
    base::FilePath* virtual_path) {
  GURL origin;
  FileSystemType file_system_type = kFileSystemTypeUnknown;

  if (!url.is_valid() || !url.SchemeIsFileSystem())
    return false;

  const struct {
    FileSystemType type;
    const char* dir;
  } kValidTypes[] = {
    { kFileSystemTypePersistent, kPersistentDir },
    { kFileSystemTypeTemporary, kTemporaryDir },
    { kFileSystemTypeIsolated, kIsolatedDir },
    { kFileSystemTypeExternal, kExternalDir },
    { kFileSystemTypeTest, kTestDir },
  };

  // A path of the inner_url contains only mount type part (e.g. "/temporary").
  DCHECK(url.inner_url());
  std::string inner_path = url.inner_url()->path();
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) {
    if (inner_path == kValidTypes[i].dir) {
      file_system_type = kValidTypes[i].type;
      break;
    }
  }

  if (file_system_type == kFileSystemTypeUnknown)
    return false;

  std::string path = net::UnescapeURLComponent(url.path(),
      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
      net::UnescapeRule::CONTROL_CHARS);

  // Ensure the path is relative.
  while (!path.empty() && path[0] == '/')
    path.erase(0, 1);

  base::FilePath converted_path = base::FilePath::FromUTF8Unsafe(path);

  // All parent references should have been resolved in the renderer.
  if (converted_path.ReferencesParent())
    return false;

  if (origin_url)
    *origin_url = url.GetOrigin();
  if (mount_type)
    *mount_type = file_system_type;
  if (virtual_path)
    *virtual_path = converted_path.NormalizePathSeparators().
        StripTrailingSeparators();

  return true;
}

FileSystemURL::FileSystemURL(const GURL& url)
    : mount_type_(kFileSystemTypeUnknown),
      type_(kFileSystemTypeUnknown),
      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
  is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_,
                                       &virtual_path_);
  path_ = virtual_path_;
  type_ = mount_type_;
}

FileSystemURL::FileSystemURL(const GURL& origin,
                             FileSystemType mount_type,
                             const base::FilePath& virtual_path)
    : is_valid_(true),
      origin_(origin),
      mount_type_(mount_type),
      virtual_path_(virtual_path.NormalizePathSeparators()),
      type_(mount_type),
      path_(virtual_path.NormalizePathSeparators()),
      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
}

FileSystemURL::FileSystemURL(const GURL& origin,
                             FileSystemType mount_type,
                             const base::FilePath& virtual_path,
                             const std::string& mount_filesystem_id,
                             FileSystemType cracked_type,
                             const base::FilePath& cracked_path,
                             const std::string& filesystem_id,
                             const FileSystemMountOption& mount_option)
    : is_valid_(true),
      origin_(origin),
      mount_type_(mount_type),
      virtual_path_(virtual_path.NormalizePathSeparators()),
      mount_filesystem_id_(mount_filesystem_id),
      type_(cracked_type),
      path_(cracked_path.NormalizePathSeparators()),
      filesystem_id_(filesystem_id),
      mount_option_(mount_option) {
}

FileSystemURL::~FileSystemURL() {}

GURL FileSystemURL::ToGURL() const {
  if (!is_valid_)
    return GURL();

  std::string url = GetFileSystemRootURI(origin_, mount_type_).spec();
  if (url.empty())
    return GURL();

  url.append(virtual_path_.AsUTF8Unsafe());

  // Build nested GURL.
  return GURL(url);
}

std::string FileSystemURL::DebugString() const {
  if (!is_valid_)
    return "invalid filesystem: URL";
  std::ostringstream ss;
  ss << GetFileSystemRootURI(origin_, mount_type_);

  // filesystem_id_ will be non empty for (and only for) cracked URLs.
  if (!filesystem_id_.empty()) {
    ss << virtual_path_.value();
    ss << " (";
    ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":";
    ss << path_.value();
    ss << ")";
  } else {
    ss << path_.value();
  }
  return ss.str();
}

bool FileSystemURL::IsParent(const FileSystemURL& child) const {
  return IsInSameFileSystem(child) &&
         path().IsParent(child.path());
}

bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const {
  return origin() == other.origin() &&
         type() == other.type() &&
         filesystem_id() == other.filesystem_id();
}

bool FileSystemURL::operator==(const FileSystemURL& that) const {
  return origin_ == that.origin_ &&
      type_ == that.type_ &&
      path_ == that.path_ &&
      filesystem_id_ == that.filesystem_id_ &&
      is_valid_ == that.is_valid_;
}

bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs,
                                           const FileSystemURL& rhs) const {
  DCHECK(lhs.is_valid_ && rhs.is_valid_);
  if (lhs.origin_ != rhs.origin_)
    return lhs.origin_ < rhs.origin_;
  if (lhs.type_ != rhs.type_)
    return lhs.type_ < rhs.type_;
  if (lhs.filesystem_id_ != rhs.filesystem_id_)
    return lhs.filesystem_id_ < rhs.filesystem_id_;
  return lhs.path_ < rhs.path_;
}

}  // namespace fileapi


text:
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTablePerusahaan extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('perusahaan', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nama');
            $table->string('id_divisi');
            $table->string('email');
            $table->string('id_kota');
            $table->string('alamat');
            $table->string('keterangan');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('perusahaan');
    }
}


text:
import { combineReducers } from 'redux'
import BoardsReducer from './reducer_boards'

const rootReducer = combineReducers({
  boards: BoardsReducer
})

export default rootReducer


text:
class ProxiesController < ApplicationController
  def show
    @proxy = Proxy.find(params[:id])
  end
end


text:
You've been through the tutorial, you've watched some videos, and now you're ready to write some Pony code. You fire up your editor, shovel coal into the compiler, and...you find yourself looking at a string of gibberish.

Don't panic! Pony's error messages try to be as helpful as possible and the ultimate goal is to improve them further. But, in the mean time, they can be a little intimidating.

This section tries to provide a short bestiary of Pony's error messages, along with a guide to understanding them.

Let's start with a simple one.

## left side must be something that can be assigned to

Suppose you wrote:

```pony
actor Main
  let x: I64 = 0
  new create(env: Env) =>
    x = 12
```

The error message would be:

```
Error:
.../a.pony:6:5: can't assign to a let or embed definition more than once
    x = 12
    ^
Error:
.../a.pony:6:7: left side must be something that can be assigned to
    x = 12
      ^
```

What happened is that you declared `x` as a constant, by writing `let x`, and then tried to assign a new value to it, 12. To fix the error, replace `let` with `val` or reconsider what value you want `x` to have.

That one error resulted in two error messages. The first, pointing to the `x`, describes the specific problem, that `x` was defined with `let`. The second, pointing to the `=`, describes a more general error, that whatever is on the left side of the assignment is not something that can be assigned to. You would get that same error message if you attempted to assign a value to a literal, like `3`.

## cannot write to a field in a box function

Suppose you create a class with a mutable field, and added a method to change the field:

```pony
class Wombat
  var color: String = "brown"
  fun dye(new_color: String) =>
    color = new_color
```

The error message would be:

```
Error:
.../a.pony:4:11: cannot write to a field in a box function. If you are trying to change state in a function use fun ref
    color = new_color
          ^
```

To understand this error message, you have to have some background. The field `color` is mutable, since it is declared with `var`, but the method `dye` does not have an explicit receiver reference capability. The default receiver reference capability is `box`, which allows `dye` to be called on any mutable or immutable `Wombat`; the `box` reference capability says that the method may read from but not write to the receiver. As a result, it is illegal to attempt to modify the receiver in the method.

To fix the error, you would need to give the `dye` method a mutable reference capability, such as `ref`: `fun ref dye(new_color: String) => ...`.

## receiver type is not a subtype of target type

Suppose you made a related, but slightly different error:

```pony
class Rainbow
  let colors: Array[String] = Array[String]()
  fun add_stripe(color: String) =>
    colors.push(color)
```

In this example, rather than trying to change the value of a field, the code calls a method which attempts to modify the object referred to by the field.

The problem is very similar to that of the last section, but the error message is significantly more complicated:

```
Error:
../a.pony:4:16: receiver type is not a subtype of target type
    colors.push(color)
               ^
    Info:
    .../a.pony:4:5: receiver type: this->Array[String val] ref
        colors.push(color)
        ^
    .../ponyc/packages/builtin/array.pony:252:3: target type: Array[String val] ref
      fun ref push(value: A): Array[A]^ =>
      ^
    .../a.pony:2:15: Array[String val] box is not a subtype of Array[String val] ref: box is not a subtype of ref
      let colors: Array[String] = Array[String]()
                  ^
```

Once again, Pony is trying to be helpful. The first few lines describe the error, in general terms that only a programming language maven would like: an incompatibility between the receiver type and the target type. However, Pony provides more information: the lines immediately after "Info:" tell you what it believes the receiver type to be and the next few lines describe what it believes the target type to be. Finally, the last few lines describe in detail what the problem is.

Unfortunately, this message does not locate the error as clearly as the previous examples.

Breaking it down, the issue seems to be with the call to `push`, with the receiver `colors`. The receiver type is `this->Array[String val] ref`; in other words, the view that this method has of a field whose type is `Array[String val] ref`. In the class `Rainbow`, the field `colors` is indeed declared with the type `Array[String]`, and the default reference capability for `String`s is `val` while the default reference capability for `Array` is `ref`.

The "target type" in this example is the type declaration for the method `push` of the class `Array`, with its type variable `A` replaced by `String` (again, with a default reference capability of `val`). The reference capability for the overall array, as required by the receiver reference capability of `push`, is `ref`. It seems that the receiver type and the target type should be pretty close.

But take another look at the final lines: what Pony thinks is the actual receiver type, `Array[String val] box`, is significantly different from what it thinks is the actual target type, `Array[String val] ref`. And a type with a reference capability of `box`, which is immutable, is indeed not a subtype of a type with a reference capability of `ref`, which *is* mutable.

The issue must lie with the one difference between the receiver type and the target type, which is the prefix "this->". The type `this->Array[String val] ref` is a viewpoint adapted type, or arrow type, that describes the `Array[String val] ref` "as seen by the receiver". The receiver, in this case, has the receiver reference capability of the method `add_stripe`, which is the default `box`. *That* is why the final type is `Array[String val] box`.

The fundamental error in this example is the same as the last: the default receiver reference capability for a method is `box`, which is immutable. This method, however, is attempting to modify the receiver, by adding another color stripe. That is not legal at all.

As an aside, while trying to figure out what is happening, you may have been misled by the declaration of the `colors` field, `let colors...`. That declaration makes the `colors` binding constant. As a result, you cannot assign a new array to the field. On the other hand, the array itself can be mutable or immutable. In this example, it is mutable, allowing `push` to be called on the `colors` field in the `add_stripe` method.

## A note on compiler versions

The error messages shown in this section are from ponyc 0.2.1-1063-g6ae110f [release], the current head of the master branch at the time this is written. The messages from other versions of the compiler may be different, to a greater or lesser degree.


text:
<script>
  setTimeout(() => {
    const iter = window.localStorage.iter || '';
    window.localStorage.iter = iter + 'a';
    if (iter.length === 10)
      return;
    window.location.href = window.location.href.replace('loop1', 'loop2');
  }, 1);
</script>>


text:
<?php

namespace JosekiTests\LeanMapperExtension;

use Joseki\LeanMapper\PackageMapper;
use LeanMapper\Entity;
use Nette\Configurator;
use Nette\Utils\Random;
use Tester\Assert;
use Tester\TestCase;

$container = require __DIR__ . '/../bootstrap.php';

class PackageMapperSchemaTest extends TestCase
{

    private function prepareConfigurator()
    {
        $configurator = new Configurator;
        $configurator->setTempDirectory(TEMP_DIR);
        $configurator->addParameters(['container' => ['class' => 'SystemContainer_' . Random::generate()]]);

        $configurator->addConfig(__DIR__ . '/config/config.local.neon', $configurator::NONE);

        return $configurator;
    }

    public function testMapperTable()
    {
        $configurator = $this->prepareConfigurator();
        $configurator->addConfig(__DIR__ . '/config/config.leanmapper.4.neon', $configurator::NONE);

        /** @var \Nette\DI\Container $container */
        $container = $configurator->createContainer();

        /** @var \Joseki\LeanMapper\PackageMapper $mapper */
        $mapper = $container->getByType('Joseki\LeanMapper\PackageMapper');
        Assert::same('myschema.book', $mapper->getTable('UnitTests\Tables\Book'));
        Assert::same('dbo.tag', $mapper->getTable('UnitTests\Tables\Tag'));

        Assert::same('UnitTests\Tables\Book', $mapper->getEntityClass('myschema.book'));
        Assert::same('UnitTests\Tables\Tag', $mapper->getEntityClass('dbo.tag'));

        Assert::same('UnitTests\Tables\Book', $mapper->getEntityClass('book'));
        Assert::same('UnitTests\Tables\Tag', $mapper->getEntityClass('tag'));
    }

    public function testMapperEntity()
    {
        $configurator = $this->prepareConfigurator();
        $configurator->addConfig(__DIR__ . '/config/config.leanmapper.5.neon', $configurator::NONE);

        /** @var \Nette\DI\Container $container */
        $container = $configurator->createContainer();

        /** @var \Joseki\LeanMapper\PackageMapper $mapper */
        $mapper = $container->getByType('Joseki\LeanMapper\PackageMapper');

        Assert::same('id', $mapper->getColumn('UnitTests\Tables\Permission', 'id'));
        Assert::same('role', $mapper->getColumn('UnitTests\Tables\Permission', 'role'));
        Assert::same('section', $mapper->getColumn('UnitTests\Tables\Permission', 'section'));

        $roleEntity = new \UnitTests\Tables\Permission;
        $reflection = $roleEntity->getReflection($mapper);
        $property = $reflection->getEntityProperty('role');

        Assert::true($property->hasRelationship());

        /** @var \LeanMapper\Relationship\HasOne $relationship */
        $relationship = $property->getRelationship();
        Assert::true($relationship instanceof \LeanMapper\Relationship\HasOne);

        $targetEntityClass = $property->getType();
        Assert::same('UnitTests\Tables\Role', $targetEntityClass);

        $targetTable = $mapper->getTable($targetEntityClass);
        Assert::same('dbo.role', $targetTable);

        $roleClass = $mapper->getEntityClass($targetTable);
        /** @var Entity $roleEntity */
        $roleEntity = new $roleClass;
        $rolePrimaryKey = $mapper->getPrimaryKey($targetTable);
        $roleProperty = $roleEntity->getReflection($mapper)->getEntityProperty($rolePrimaryKey);

        Assert::same('string', $roleProperty->getType());
        Assert::same('role', $relationship->getColumnReferencingTargetTable());
    }

    public function testRelationshipTable()
    {
        $mapper = new PackageMapper();
        $mapper->setDefaultSchema('dbo');
        $sourceTable = 'dbo.user';
        $targetTable = 'dbo.role';
        Assert::same('dbo.user_role', $mapper->getRelationshipTable($sourceTable, $targetTable));
    }

    public function testRelationshipColumn()
    {
        $mapper = new PackageMapper([], [], 'dbo');
        $sourceTable = 'dbo.user';
        $targetTable = 'dbo.role';
        Assert::same('role', $mapper->getRelationshipColumn($sourceTable, $targetTable));
    }

}

run(new PackageMapperSchemaTest());


text:
import reducer from '../reducers'
import createLogger from 'redux-logger'
import thunk from 'redux-thunk'
import {createStore, applyMiddleware} from 'redux'

const logger = createLogger();
const middleware = [thunk, logger];

const initialState = {};

export const store = createStore(reducer, initialState, applyMiddleware(...middleware));

store.subscribe(() => {
	console.log('store change:', store.getState());
})


text:
package com.radex392.temporalrelativity.item;

public class ItemTRIngot extends ItemTR
{
	public ItemTRIngot(String name)
	{
		super(name);
	}
}


text:
using System.Linq;
using EF_Split_Projector.Helpers;
using NUnit.Framework;
using Tests.Helpers;
using Tests.TestContext.DataModels;

namespace Tests
{
    [TestFixture]
    public class BatchQueryTests : IntegratedTestsBase
    {
        [Test]
        public void BatchingQueriesReturnsExpectedResults()
        {
            TestHelper.CreateObjectGraphAndInsertIntoDatabase<Inventory>();
            TestHelper.CreateObjectGraphAndInsertIntoDatabase<Inventory>();
            TestHelper.CreateObjectGraphAndInsertIntoDatabase<Inventory>();

            var query1 = TestHelper.Context.Inventory.Select(i => new InventorySelect
                {
                    ItemDescription = i.Item.Description
                });
            var query2 = TestHelper.Context.Inventory.Select(i => new InventorySelect
                {
                    Quantity = i.Quantity
                });

            var expected1 = query1.ToList();
            var expected2 = query2.ToList();

            var results = BatchQueriesHelper.ExecuteBatchQueries(query1, query2);

            EquivalentHelper.AreEquivalent(expected1, results[0]);
            EquivalentHelper.AreEquivalent(expected2, results[1]);
        }
    }
}


text:
var fs = require('fs');

module.exports.index = function(req, res){
  fs.readFile(__dirname + '/../client/index.html', 'utf8', function(err, text){
    res.send(text);
  });
};


text:
#ifndef INLINE_SW_HELPER_H
#define INLINE_SW_HELPER_H

#include "pipe/p_compiler.h"
#include "util/u_debug.h"
#include "state_tracker/sw_winsys.h"

/* Helper function to choose and instantiate one of the software rasterizers:
 * llvmpipe, softpipe.
 */

#ifdef GALLIUM_SOFTPIPE
#include "softpipe/sp_public.h"
#endif

#ifdef GALLIUM_LLVMPIPE
#include "llvmpipe/lp_public.h"
#endif

static INLINE struct pipe_screen *
sw_screen_create_named(struct sw_winsys *winsys, const char *driver)
{
   struct pipe_screen *screen = NULL;

#if defined(GALLIUM_LLVMPIPE)
   if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
      screen = llvmpipe_create_screen(winsys);
#endif

#if defined(GALLIUM_SOFTPIPE)
   if (screen == NULL)
      screen = softpipe_create_screen(winsys);
#endif

   return screen;
}

static INLINE struct pipe_screen *
sw_screen_create(struct sw_winsys *winsys)
{
   const char *default_driver;
   const char *driver;

#if defined(GALLIUM_LLVMPIPE)
   default_driver = "llvmpipe";
#elif defined(GALLIUM_SOFTPIPE)
   default_driver = "softpipe";
#else
   default_driver = "";
#endif

   driver = debug_get_option("GALLIUM_DRIVER", default_driver);
   return sw_screen_create_named(winsys, driver);
}

#if defined(GALLIUM_SOFTPIPE)
#if defined(DRI_TARGET)
#include "target-helpers/inline_debug_helper.h"
#include "sw/dri/dri_sw_winsys.h"
#include "dri_screen.h"

const __DRIextension **__driDriverGetExtensions_swrast(void);

PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void)
{
   globalDriverAPI = &galliumsw_driver_api;
   return galliumsw_driver_extensions;
}

INLINE struct pipe_screen *
drisw_create_screen(struct drisw_loader_funcs *lf)
{
   struct sw_winsys *winsys = NULL;
   struct pipe_screen *screen = NULL;

   winsys = dri_create_sw_winsys(lf);
   if (winsys == NULL)
      return NULL;

   screen = sw_screen_create(winsys);
   if (screen == NULL) {
      winsys->destroy(winsys);
      return NULL;
   }

   screen = debug_screen_wrap(screen);
   return screen;
}
#endif // DRI_TARGET
#endif // GALLIUM_SOFTPIPE

#endif


text:
<?php namespace Mews\Thumb\Facades;

use Illuminate\Support\Facades\Facade;

class Thumb extends Facade {

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'thumb'; }

}


text:
FROM scratch

# https://github.com/tianon/docker-brew-debian/blob/0a2d20ca8e26f7bf6a5cc3ce2727eb6cc1894ef9/jessie/rootfs.tar.xz
ADD rootfs.tar.xz /

RUN \
    # http proxy
    export http_proxy=http://proxy.pal.sap.corp:8080 &&\
    export https_proxy=http://proxy.pal.sap.corp:8080 &&\
    export DEBIAN_FRONTEND=noninteractive &&\
    apt-get update &&\
    apt-get install -y --force-yes --no-install-recommends \
     unzip curl ca-certificates liblz4-tool p7zip-full net-tools &&\
    apt-get clean autoclean &&\
    rm -rf /var/lib/apt/lists/* &&\
    rm -rf /var/log/* &&\
    unset http_proxy https_proxy &&\
    # import sap_root_ca
    curl -s -o /etc/ssl/certs/sap_root_ca.pem http://172.17.0.1:8000/sap_root_ca.pem &&\
    update-ca-certificates --fresh &&\
    # test
    curl -i -s https://media.hypercd.sapanywhere.sap.corp | head &&\
    # done
    echo 'done'

CMD ["/bin/bash"]


text:
<?php /*4b24938a83640f3fed2d025fa54dff50adf84056*/

/**
 * @package    GoodForNothing Core
 * @version    1.0.0 Alpha 4
 * @since      1.0.0 Alpha 4
 * @author     GoodForNothing Labs
 * @copyright  Copyright © 2012-2015 GoodForNothing Labs <https://gfnlabs.com/>
 * @license    https://gfnlabs.com/legal/license
 * @link       https://gfnlabs.com/
 */
class GFNCore_Installer_Handler_Style extends GFNCore_Installer_Handler_Abstract
{
    public function handle($addOnId)
    {
        $addOnId = strtolower($addOnId);
        $root = XenForo_Application::getInstance()->getRootDir() . '/styles';
        if ((!$root = realpath($root)) || !is_dir($root))
        {
            return;
        }

        $source = $root . '/default/' . $addOnId;
        if ((!$source = realpath($source)) || !is_dir($source))
        {
            return;
        }

        $available = GFNCore_Helper_Directory::read($root, false);

        foreach ($available as $i => $path)
        {
            if (is_dir($path) && (basename($path) != 'default'))
            {
                $target = $path . '/' . $addOnId;
                GFNCore_Helper_Directory::copy($source, $target);
            }
        }
    }
}


text:
require 'spec_helper'

describe Expedition do
  pending "add some examples to (or delete) #{__FILE__}"
end


text:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using SpainHoliday.SepaWriter.Utils;

namespace SpainHoliday.SepaWriter
{
    /// <summary>
    ///     Manage SEPA (Single Euro Payments Area) CreditTransfer for SEPA or international order.
    ///     Only one PaymentInformation is managed but it can manage multiple transactions.
    /// </summary>
    public class SepaDebitTransfer : SepaTransfer<SepaDebitTransferTransaction>
    {
        /// <summary>
        ///     creditor account ISO currency code (default is EUR)
        /// </summary>
        public string CreditorAccountCurrency { get; set; }

        /// <summary>
        ///     Unique and unambiguous identification of a person. SEPA creditor
        /// </summary>
        public string PersonId { get; set; }

        /// <summary>
        /// Create a Sepa Debit Transfer using Pain.008.001.02 schema
        /// </summary>
        public SepaDebitTransfer()
        {
            CreditorAccountCurrency = Constant.EuroCurrency;
            LocalInstrumentCode = "CORE";
            schema = SepaSchema.Pain00800102;
        }

        public SepaDebitTransfer(string creditorAccountCurrencyCode)
        {
            if (string.IsNullOrWhiteSpace(creditorAccountCurrencyCode) || creditorAccountCurrencyCode.Length != 3)
            {
                throw new SepaRuleException("Currency has to be a valid 3 character code in ISO format.");
            }
            CreditorAccountCurrency = creditorAccountCurrencyCode.ToUpper();
            LocalInstrumentCode = "CORE";
            schema = SepaSchema.Pain00800102;
        }

        /// <summary>
        ///     Creditor IBAN data
        /// </summary>
        /// <exception cref="SepaRuleException">If creditor to set is not valid.</exception>
        public SepaIbanData Creditor
        {
            get { return SepaIban; }
            set
            {
                if (!value.IsValid || value.UnknownBic)
                    throw new SepaRuleException("Creditor IBAN data are invalid.");
                SepaIban = value;
            }
        }

        /// <summary>
        ///     Is Mandatory data are set ? In other case a SepaRuleException will be thrown
        /// </summary>
        /// <exception cref="SepaRuleException">If mandatory data is missing.</exception>
        protected override void CheckMandatoryData()
        {
            base.CheckMandatoryData();

            if (Creditor == null)
            {
                throw new SepaRuleException("The creditor is mandatory.");
            }
        }

        /// <summary>
        ///     Add an existing transfer transaction
        /// </summary>
        /// <param name="transfer"></param>
        /// <exception cref="ArgumentNullException">If transfert is null.</exception>
        public void AddDebitTransfer(SepaDebitTransferTransaction transfer)
        {
            AddTransfer(transfer);
        }

        /// <summary>
        ///     Generate the XML structure
        /// </summary>
        /// <returns></returns>
        protected override XmlDocument GenerateXml()
        {
            CheckMandatoryData();

            var xml = new XmlDocument();
            xml.AppendChild(xml.CreateXmlDeclaration("1.0", Encoding.UTF8.BodyName, "yes"));
            var el = (XmlElement)xml.AppendChild(xml.CreateElement("Document"));
            el.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            el.SetAttribute("xmlns", "urn:iso:std:iso:20022:tech:xsd:" + SepaSchemaUtils.SepaSchemaToString(schema));
            el.NewElement("CstmrDrctDbtInitn");

            // Part 1: Group Header
            var grpHdr = XmlUtils.GetFirstElement(xml, "CstmrDrctDbtInitn").NewElement("GrpHdr");
            grpHdr.NewElement("MsgId", MessageIdentification);
            grpHdr.NewElement("CreDtTm", StringUtils.FormatDateTime(CreationDate));
            grpHdr.NewElement("NbOfTxs", numberOfTransactions);
            grpHdr.NewElement("CtrlSum", StringUtils.FormatAmount(headerControlSum));
            grpHdr.NewElement("InitgPty").NewElement("Nm", InitiatingPartyName);
			if (InitiatingPartyId != null) {
				XmlUtils.GetFirstElement(grpHdr, "InitgPty").
					NewElement("Id").NewElement("OrgId").
					NewElement("Othr").NewElement("Id", InitiatingPartyId);
			}

            // Part 2: Payment Information for each Sequence Type.
            foreach (SepaSequenceType seqTp in Enum.GetValues(typeof(SepaSequenceType)))
            {
                var seqTransactions = transactions.FindAll(d => d.SequenceType == seqTp);
                var pmtInf = GeneratePaymentInformation(xml, seqTp, seqTransactions);
                // If a payment information has been created
                if (pmtInf != null)
                {
                    // Part 3: Debit Transfer Transaction Information
                    foreach (var transfer in seqTransactions)
                    {
                        GenerateTransaction(pmtInf, transfer);
                    }
                }
            }

            return xml;
        }

        /// <summary>
        /// Generate a Payment Information node for a Sequence Type.
        /// </summary>
        /// <param name="xml">The XML object to write</param>
        /// <param name="sqType">The Sequence Type</param>
        /// <param name="seqTransactions">The transactions of the specified type</param>
        private XmlElement GeneratePaymentInformation(XmlDocument xml, SepaSequenceType sqType, IEnumerable<SepaDebitTransferTransaction> seqTransactions)
        {
            int controlNumber = 0;
            decimal controlSum = 0;

            // We check the number of transaction to write and the sum due to the Sequence Type.
            foreach (var transfer in seqTransactions)
            {
                controlNumber += 1;
                controlSum += transfer.Amount;
            }

            // If there is no transaction, we end the method here.
            if (controlNumber == 0)
                return null;

            var pmtInf = XmlUtils.GetFirstElement(xml, "CstmrDrctDbtInitn").NewElement("PmtInf");
            pmtInf.NewElement("PmtInfId", PaymentInfoId ?? MessageIdentification);
            if (CategoryPurposeCode != null)
                pmtInf.NewElement("CtgyPurp").NewElement("Cd", CategoryPurposeCode);

            pmtInf.NewElement("PmtMtd", Constant.DebitTransfertPaymentMethod);
            pmtInf.NewElement("NbOfTxs", controlNumber);
            pmtInf.NewElement("CtrlSum", StringUtils.FormatAmount(controlSum));

            var pmtTpInf = pmtInf.NewElement("PmtTpInf");
            pmtTpInf.NewElement("SvcLvl").NewElement("Cd", "SEPA");
            pmtTpInf.NewElement("LclInstrm").NewElement("Cd", LocalInstrumentCode);
            pmtTpInf.NewElement("SeqTp", SepaSequenceTypeUtils.SepaSequenceTypeToString(sqType));

            pmtInf.NewElement("ReqdColltnDt", StringUtils.FormatDate(RequestedExecutionDate));
            pmtInf.NewElement("Cdtr").NewElement("Nm", Creditor.Name);

            var dbtrAcct = pmtInf.NewElement("CdtrAcct");
            dbtrAcct.NewElement("Id").NewElement("IBAN", Creditor.Iban);
            dbtrAcct.NewElement("Ccy", CreditorAccountCurrency);

            pmtInf.NewElement("CdtrAgt").NewElement("FinInstnId").NewElement("BIC", Creditor.Bic);
            pmtInf.NewElement("ChrgBr", "SLEV");

            var othr = pmtInf.NewElement("CdtrSchmeId").NewElement("Id")
                    .NewElement("PrvtId")
                        .NewElement("Othr");
            othr.NewElement("Id", PersonId);
            othr.NewElement("SchmeNm").NewElement("Prtry", "SEPA");

            return pmtInf;
        }

        /// <summary>
        /// Generate the Transaction XML part
        /// </summary>
        /// <param name="pmtInf">The root nodes for a transaction</param>
        /// <param name="transfer">The transaction to generate</param>
        private static void GenerateTransaction(XmlElement pmtInf, SepaDebitTransferTransaction transfer)
        {
            var cdtTrfTxInf = pmtInf.NewElement("DrctDbtTxInf");
            var pmtId = cdtTrfTxInf.NewElement("PmtId");
            if (transfer.Id != null)
                pmtId.NewElement("InstrId", transfer.Id);
            pmtId.NewElement("EndToEndId", transfer.EndToEndId);
            cdtTrfTxInf.NewElement("InstdAmt", StringUtils.FormatAmount(transfer.Amount)).SetAttribute("Ccy", transfer.Currency.ToUpper());

            var mndtRltdInf = cdtTrfTxInf.NewElement("DrctDbtTx").NewElement("MndtRltdInf");
            mndtRltdInf.NewElement("MndtId", transfer.MandateIdentification);
            mndtRltdInf.NewElement("DtOfSgntr", StringUtils.FormatDate(transfer.DateOfSignature));

            XmlUtils.CreateBic(cdtTrfTxInf.NewElement("DbtrAgt"), transfer.Debtor);
            cdtTrfTxInf.NewElement("Dbtr").NewElement("Nm", transfer.Debtor.Name);
            cdtTrfTxInf.NewElement("DbtrAcct").NewElement("Id").NewElement("IBAN", transfer.Debtor.Iban);

            if (!string.IsNullOrEmpty(transfer.RemittanceInformation))
                cdtTrfTxInf.NewElement("RmtInf").NewElement("Ustrd", transfer.RemittanceInformation);
        }

        protected override bool CheckSchema(SepaSchema aSchema)
        {
            return aSchema == SepaSchema.Pain00800102 || aSchema == SepaSchema.Pain00800103;
        }
    }
}


text:
#include <cassert>

#include "flutter/fml/backtrace.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/icu_util.h"
#include "flutter/fml/logging.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "txt_test_utils.h"

int main(int argc, char** argv) {
  fml::InstallCrashHandler();
  fml::CommandLine cmd = fml::CommandLineFromArgcArgv(argc, argv);
  txt::SetCommandLine(cmd);
  txt::SetFontDir(flutter::testing::GetFixturesPath());
  if (txt::GetFontDir().length() <= 0) {
    FML_LOG(ERROR) << "Font directory not set via txt::SetFontDir.";
    return EXIT_FAILURE;
  }
  FML_DCHECK(txt::GetFontDir().length() > 0);
#if defined(OS_FUCHSIA)
  fml::icu::InitializeICU("/pkg/data/icudtl.dat");
#else
  std::string icudtl_path =
      cmd.GetOptionValueWithDefault("icu-data-file-path", "icudtl.dat");
  fml::icu::InitializeICU(icudtl_path);
#endif
  SkGraphics::Init();
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}