diff --git a/unum/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go b/unum/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go
new file mode 100644
index 0000000..fdde288
--- /dev/null
+++ b/unum/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go
@@ -0,0 +1,371 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package xml
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"sync"
+)
+
+// typeInfo holds details for the xml representation of a type.
+type typeInfo struct {
+	xmlname *fieldInfo
+	fields  []fieldInfo
+}
+
+// fieldInfo holds details for the xml representation of a single field.
+type fieldInfo struct {
+	idx     []int
+	name    string
+	xmlns   string
+	flags   fieldFlags
+	parents []string
+}
+
+type fieldFlags int
+
+const (
+	fElement fieldFlags = 1 << iota
+	fAttr
+	fCharData
+	fInnerXml
+	fComment
+	fAny
+
+	fOmitEmpty
+
+	fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny
+)
+
+var tinfoMap = make(map[reflect.Type]*typeInfo)
+var tinfoLock sync.RWMutex
+
+var nameType = reflect.TypeOf(Name{})
+
+// getTypeInfo returns the typeInfo structure with details necessary
+// for marshalling and unmarshalling typ.
+func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
+	tinfoLock.RLock()
+	tinfo, ok := tinfoMap[typ]
+	tinfoLock.RUnlock()
+	if ok {
+		return tinfo, nil
+	}
+	tinfo = &typeInfo{}
+	if typ.Kind() == reflect.Struct && typ != nameType {
+		n := typ.NumField()
+		for i := 0; i < n; i++ {
+			f := typ.Field(i)
+			if f.PkgPath != "" || f.Tag.Get("xml") == "-" {
+				continue // Private field
+			}
+
+			// For embedded structs, embed its fields.
+			if f.Anonymous {
+				t := f.Type
+				if t.Kind() == reflect.Ptr {
+					t = t.Elem()
+				}
+				if t.Kind() == reflect.Struct {
+					inner, err := getTypeInfo(t)
+					if err != nil {
+						return nil, err
+					}
+					if tinfo.xmlname == nil {
+						tinfo.xmlname = inner.xmlname
+					}
+					for _, finfo := range inner.fields {
+						finfo.idx = append([]int{i}, finfo.idx...)
+						if err := addFieldInfo(typ, tinfo, &finfo); err != nil {
+							return nil, err
+						}
+					}
+					continue
+				}
+			}
+
+			finfo, err := structFieldInfo(typ, &f)
+			if err != nil {
+				return nil, err
+			}
+
+			if f.Name == "XMLName" {
+				tinfo.xmlname = finfo
+				continue
+			}
+
+			// Add the field if it doesn't conflict with other fields.
+			if err := addFieldInfo(typ, tinfo, finfo); err != nil {
+				return nil, err
+			}
+		}
+	}
+	tinfoLock.Lock()
+	tinfoMap[typ] = tinfo
+	tinfoLock.Unlock()
+	return tinfo, nil
+}
+
+// structFieldInfo builds and returns a fieldInfo for f.
+func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, error) {
+	finfo := &fieldInfo{idx: f.Index}
+
+	// Split the tag from the xml namespace if necessary.
+	tag := f.Tag.Get("xml")
+	if i := strings.Index(tag, " "); i >= 0 {
+		finfo.xmlns, tag = tag[:i], tag[i+1:]
+	}
+
+	// Parse flags.
+	tokens := strings.Split(tag, ",")
+	if len(tokens) == 1 {
+		finfo.flags = fElement
+	} else {
+		tag = tokens[0]
+		for _, flag := range tokens[1:] {
+			switch flag {
+			case "attr":
+				finfo.flags |= fAttr
+			case "chardata":
+				finfo.flags |= fCharData
+			case "innerxml":
+				finfo.flags |= fInnerXml
+			case "comment":
+				finfo.flags |= fComment
+			case "any":
+				finfo.flags |= fAny
+			case "omitempty":
+				finfo.flags |= fOmitEmpty
+			}
+		}
+
+		// Validate the flags used.
+		valid := true
+		switch mode := finfo.flags & fMode; mode {
+		case 0:
+			finfo.flags |= fElement
+		case fAttr, fCharData, fInnerXml, fComment, fAny:
+			if f.Name == "XMLName" || tag != "" && mode != fAttr {
+				valid = false
+			}
+		default:
+			// This will also catch multiple modes in a single field.
+			valid = false
+		}
+		if finfo.flags&fMode == fAny {
+			finfo.flags |= fElement
+		}
+		if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 {
+			valid = false
+		}
+		if !valid {
+			return nil, fmt.Errorf("xml: invalid tag in field %s of type %s: %q",
+				f.Name, typ, f.Tag.Get("xml"))
+		}
+	}
+
+	// Use of xmlns without a name is not allowed.
+	if finfo.xmlns != "" && tag == "" {
+		return nil, fmt.Errorf("xml: namespace without name in field %s of type %s: %q",
+			f.Name, typ, f.Tag.Get("xml"))
+	}
+
+	if f.Name == "XMLName" {
+		// The XMLName field records the XML element name. Don't
+		// process it as usual because its name should default to
+		// empty rather than to the field name.
+		finfo.name = tag
+		return finfo, nil
+	}
+
+	if tag == "" {
+		// If the name part of the tag is completely empty, get
+		// default from XMLName of underlying struct if feasible,
+		// or field name otherwise.
+		if xmlname := lookupXMLName(f.Type); xmlname != nil {
+			finfo.xmlns, finfo.name = xmlname.xmlns, xmlname.name
+		} else {
+			finfo.name = f.Name
+		}
+		return finfo, nil
+	}
+
+	if finfo.xmlns == "" && finfo.flags&fAttr == 0 {
+		// If it's an element no namespace specified, get the default
+		// from the XMLName of enclosing struct if possible.
+		if xmlname := lookupXMLName(typ); xmlname != nil {
+			finfo.xmlns = xmlname.xmlns
+		}
+	}
+
+	// Prepare field name and parents.
+	parents := strings.Split(tag, ">")
+	if parents[0] == "" {
+		parents[0] = f.Name
+	}
+	if parents[len(parents)-1] == "" {
+		return nil, fmt.Errorf("xml: trailing '>' in field %s of type %s", f.Name, typ)
+	}
+	finfo.name = parents[len(parents)-1]
+	if len(parents) > 1 {
+		if (finfo.flags & fElement) == 0 {
+			return nil, fmt.Errorf("xml: %s chain not valid with %s flag", tag, strings.Join(tokens[1:], ","))
+		}
+		finfo.parents = parents[:len(parents)-1]
+	}
+
+	// If the field type has an XMLName field, the names must match
+	// so that the behavior of both marshalling and unmarshalling
+	// is straightforward and unambiguous.
+	if finfo.flags&fElement != 0 {
+		ftyp := f.Type
+		xmlname := lookupXMLName(ftyp)
+		if xmlname != nil && xmlname.name != finfo.name {
+			return nil, fmt.Errorf("xml: name %q in tag of %s.%s conflicts with name %q in %s.XMLName",
+				finfo.name, typ, f.Name, xmlname.name, ftyp)
+		}
+	}
+	return finfo, nil
+}
+
+// lookupXMLName returns the fieldInfo for typ's XMLName field
+// in case it exists and has a valid xml field tag, otherwise
+// it returns nil.
+func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) {
+	for typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+	}
+	if typ.Kind() != reflect.Struct {
+		return nil
+	}
+	for i, n := 0, typ.NumField(); i < n; i++ {
+		f := typ.Field(i)
+		if f.Name != "XMLName" {
+			continue
+		}
+		finfo, err := structFieldInfo(typ, &f)
+		if finfo.name != "" && err == nil {
+			return finfo
+		}
+		// Also consider errors as a non-existent field tag
+		// and let getTypeInfo itself report the error.
+		break
+	}
+	return nil
+}
+
+func min(a, b int) int {
+	if a <= b {
+		return a
+	}
+	return b
+}
+
+// addFieldInfo adds finfo to tinfo.fields if there are no
+// conflicts, or if conflicts arise from previous fields that were
+// obtained from deeper embedded structures than finfo. In the latter
+// case, the conflicting entries are dropped.
+// A conflict occurs when the path (parent + name) to a field is
+// itself a prefix of another path, or when two paths match exactly.
+// It is okay for field paths to share a common, shorter prefix.
+func addFieldInfo(typ reflect.Type, tinfo *typeInfo, newf *fieldInfo) error {
+	var conflicts []int
+Loop:
+	// First, figure all conflicts. Most working code will have none.
+	for i := range tinfo.fields {
+		oldf := &tinfo.fields[i]
+		if oldf.flags&fMode != newf.flags&fMode {
+			continue
+		}
+		if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns {
+			continue
+		}
+		minl := min(len(newf.parents), len(oldf.parents))
+		for p := 0; p < minl; p++ {
+			if oldf.parents[p] != newf.parents[p] {
+				continue Loop
+			}
+		}
+		if len(oldf.parents) > len(newf.parents) {
+			if oldf.parents[len(newf.parents)] == newf.name {
+				conflicts = append(conflicts, i)
+			}
+		} else if len(oldf.parents) < len(newf.parents) {
+			if newf.parents[len(oldf.parents)] == oldf.name {
+				conflicts = append(conflicts, i)
+			}
+		} else {
+			if newf.name == oldf.name {
+				conflicts = append(conflicts, i)
+			}
+		}
+	}
+	// Without conflicts, add the new field and return.
+	if conflicts == nil {
+		tinfo.fields = append(tinfo.fields, *newf)
+		return nil
+	}
+
+	// If any conflict is shallower, ignore the new field.
+	// This matches the Go field resolution on embedding.
+	for _, i := range conflicts {
+		if len(tinfo.fields[i].idx) < len(newf.idx) {
+			return nil
+		}
+	}
+
+	// Otherwise, if any of them is at the same depth level, it's an error.
+	for _, i := range conflicts {
+		oldf := &tinfo.fields[i]
+		if len(oldf.idx) == len(newf.idx) {
+			f1 := typ.FieldByIndex(oldf.idx)
+			f2 := typ.FieldByIndex(newf.idx)
+			return &TagPathError{typ, f1.Name, f1.Tag.Get("xml"), f2.Name, f2.Tag.Get("xml")}
+		}
+	}
+
+	// Otherwise, the new field is shallower, and thus takes precedence,
+	// so drop the conflicting fields from tinfo and append the new one.
+	for c := len(conflicts) - 1; c >= 0; c-- {
+		i := conflicts[c]
+		copy(tinfo.fields[i:], tinfo.fields[i+1:])
+		tinfo.fields = tinfo.fields[:len(tinfo.fields)-1]
+	}
+	tinfo.fields = append(tinfo.fields, *newf)
+	return nil
+}
+
+// A TagPathError represents an error in the unmarshalling process
+// caused by the use of field tags with conflicting paths.
+type TagPathError struct {
+	Struct       reflect.Type
+	Field1, Tag1 string
+	Field2, Tag2 string
+}
+
+func (e *TagPathError) Error() string {
+	return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2)
+}
+
+// value returns v's field value corresponding to finfo.
+// It's equivalent to v.FieldByIndex(finfo.idx), but initializes
+// and dereferences pointers as necessary.
+func (finfo *fieldInfo) value(v reflect.Value) reflect.Value {
+	for i, x := range finfo.idx {
+		if i > 0 {
+			t := v.Type()
+			if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
+				if v.IsNil() {
+					v.Set(reflect.New(v.Type().Elem()))
+				}
+				v = v.Elem()
+			}
+		}
+		v = v.Field(x)
+	}
+	return v
+}
