func (s *Schema) UnmarshalJSON(data []byte) error {
	m := map[string]interface{}{}
	if err := json.Unmarshal(data, &m); err != nil {
		return err
	}
	return s.Extract(m)
}
UnmarshalJSON takes a JSON string and initializes
the schema
package schema
import (
	"encoding/json"
	"regexp"
	"strconv"
	"github.com/lestrrat/go-pdebug"
	"github.com/pkg/errors"
)
func extractNumber(n *Number, m map[string]interface{}, s string) error {
	v, ok := m[s]
	if !ok {
		return nil
	}
	val, ok := v.(float64)
	if !ok {
		return errors.Wrap(errInvalidType("float64", v), "failed to extract number")
	}
	n.Val = val
	n.Initialized = true
	return nil
}
func extractInt(n *Integer, m map[string]interface{}, s string) error {
	v, ok := m[s]
	if !ok {
		return nil
	}
	val, ok := v.(float64)
	if !ok {
		return errors.Wrap(errInvalidType("float64", v), "failed to extract int")
	}
	n.Val = int(val)
	n.Initialized = true
	return nil
}
func extractBool(b *Bool, m map[string]interface{}, s string, def bool) error {
	b.Default = def
	v, ok := m[s]
	if !ok {
		return nil
	}
	val, ok := v.(bool)
	if !ok {
		return errors.Wrap(errInvalidType("bool", v), "failed to extract bool")
	}
	b.Val = val
	b.Initialized = true
	return nil
}
func extractString(s *string, m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	val, ok := v.(string)
	if !ok {
		return errors.Wrap(errInvalidType("string", v), "failed to extract string")
	}
	*s = val
	return nil
}
func convertStringList(l *[]string, v interface{}) error {
	switch val := v.(type) {
	case string:  
		*l = []string{val}
	case []interface{}:  
		*l = make([]string, len(val))
		for i, x := range val {
			s, ok := x.(string)
			if !ok {
				return ErrExpectedArrayOfString
			}
			(*l)[i] = s
		}
	default:
		return ErrExpectedArrayOfString
	}
	return nil
}
func extractStringList(l *[]string, m map[string]interface{}, s string) error {
	v, ok := m[s]
	if !ok {
		return nil
	}
	return convertStringList(l, v)
}
func extractFormat(f *Format, m map[string]interface{}, s string) error {
	var v string
	if err := extractString(&v, m, s); err != nil {
		return err
	}
	*f = Format(v)
	return nil
}
func extractJSPointer(s *string, m map[string]interface{}, name string) error {
	return extractString(s, m, name)
}
func extractInterface(r *interface{}, m map[string]interface{}, s string) error {
	if v, ok := m[s]; ok {
		*r = v
	}
	return nil
}
func extractInterfaceList(l *[]interface{}, m map[string]interface{}, s string) error {
	v, ok := m[s]
	if !ok {
		return nil
	}
	val, ok := v.([]interface{})
	if !ok {
		return errors.Wrap(
			errInvalidType("[]interface{}", v),
			"failed to extract interface list",
		)
	}
	*l = make([]interface{}, len(val))
	copy(*l, val)
	return nil
}
func extractRegexp(r **regexp.Regexp, m map[string]interface{}, s string) error {
	v, ok := m[s]
	if !ok {
		return nil
	}
	val, ok := v.(string)
	if !ok {
		return errors.Wrap(
			errInvalidType("string", v),
			"failed to extract regular expression",
		)
	}
	rx, err := regexp.Compile(val)
	if err != nil {
		return errors.Wrap(
			errors.Wrapf(
				err,
				"failed to compile regular expression: %s",
				strconv.Quote(val),
			),
			"failed to extract regular expression",
		)
	}
	*r = rx
	return nil
}
func extractSchema(s **Schema, m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	if pdebug.Enabled {
		pdebug.Printf("Found property '%s'", name)
	}
	val, ok := v.(map[string]interface{})
	if !ok {
		return errors.Wrap(
			errInvalidType("map[string]interface{}", v),
			"failed to extract schema",
		)
	}
	return extractSingleSchema(s, val)
}
func extractSingleSchema(s **Schema, m map[string]interface{}) error {
	*s = New()
	if err := (*s).Extract(m); err != nil {
		return errors.Wrap(err, "failed to extract schema")
	}
	return nil
}
func (l *SchemaList) extractIfPresent(m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	if pdebug.Enabled {
		pdebug.Printf("Found property '%s'", name)
	}
	return l.Extract(v)
}
func (l *SchemaList) Extract(v interface{}) error {
	switch val := v.(type) {
	case []interface{}:
		*l = make([]*Schema, len(val))
		var s *Schema
		for i, d := range val {
			m, ok := d.(map[string]interface{})
			if !ok {
				return errors.Wrap(
					errInvalidType("map[string]interface{}", d),
					"failed to extract schema list",
				)
			}
			if err := extractSingleSchema(&s, m); err != nil {
				return errors.Wrap(err, "failed to extract schema list")
			}
			(*l)[i] = s
		}
		return nil
	case map[string]interface{}:
		var s *Schema
		if err := extractSingleSchema(&s, val); err != nil {
			return errors.Wrap(err, "failed to extract schema list")
		}
		*l = []*Schema{s}
		return nil
	default:
		return errors.Wrap(
			errInvalidType("[]*Schema or *Schema", v),
			"failed to extract schema list",
		)
	}
}
func extractSchemaMapEntry(s *Schema, name string, m map[string]interface{}) error {
	if pdebug.Enabled {
		g := pdebug.Marker("Schema map entry '%s'", name)
		defer g.End()
	}
	return s.Extract(m)
}
func extractSchemaMap(m map[string]interface{}, name string) (map[string]*Schema, error) {
	v, ok := m[name]
	if !ok {
		return nil, nil
	}
	val, ok := v.(map[string]interface{})
	if !ok {
		return nil, errors.Wrap(
			errInvalidType("map[string]interface{}", v),
			"failed to extract schema map",
		)
	}
	r := make(map[string]*Schema)
	for k, data := range val {
		m, ok := data.(map[string]interface{})
		if !ok {
			return nil, errors.Wrap(
				errInvalidType("map[string]interface{}", data),
				"failed to extract sub field",
			)
		}
		s := New()
		if err := extractSchemaMapEntry(s, k, m); err != nil {
			return nil, err
		}
		r[k] = s
		if k == "domain" {
			if pdebug.Enabled {
				pdebug.Printf("after extractSchemaMapEntry: %#v", s.Extras)
			}
		}
	}
	return r, nil
}
func extractRegexpToSchemaMap(m map[string]interface{}, name string) (map[*regexp.Regexp]*Schema, error) {
	v, ok := m[name]
	if !ok {
		return nil, nil
	}
	val, ok := v.(map[string]interface{})
	if !ok {
		return nil, errors.Wrap(
			errInvalidType("map[string]interface{}", v),
			"failed to extract regexp to schema map",
		)
	}
	r := make(map[*regexp.Regexp]*Schema)
	for k, data := range val {
		m, ok := data.(map[string]interface{})
		if !ok {
			return nil, errors.Wrap(
				errInvalidType("map[string]interface{}", data),
				"failed to extract regexp to schema map",
			)
		}
		s := New()
		if err := s.Extract(m); err != nil {
			return nil, errors.Wrap(err, "failed to extract schema within schema map")
		}
		rx, err := regexp.Compile(k)
		if err != nil {
			return nil, errors.Wrap(err, "failed to compile regular expression for regexp to schema map")
		}
		r[rx] = s
	}
	return r, nil
}
func extractItems(res **ItemSpec, m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	if pdebug.Enabled {
		pdebug.Printf("Found array element '%s'", name)
	}
	tupleMode := false
	switch v.(type) {
	case []interface{}:
		tupleMode = true
	case map[string]interface{}:
	default:
		return errors.Wrap(
			errInvalidType("[]interface{} or map[string]interface{}", v),
			"failed to extract items",
		)
	}
	items := ItemSpec{}
	items.TupleMode = tupleMode
	var err error
	if err = items.Schemas.extractIfPresent(m, name); err != nil {
		return errors.Wrap(err, "failed to schema for item")
	}
	*res = &items
	return nil
}
func extractDependecies(res *DependencyMap, m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	m, ok = v.(map[string]interface{})
	if !ok {
		return errors.Wrap(
			errInvalidType("map[string]interface{}", v),
			"failed to extract dependencies",
		)
	}
	if len(m) == 0 {
		return nil
	}
	return res.extract(m)
}
func extractType(pt *PrimitiveTypes, m map[string]interface{}, name string) error {
	v, ok := m[name]
	if !ok {
		return nil
	}
	switch val := v.(type) {
	case string:
		t, err := primitiveFromString(val)
		if err != nil {
			return errors.Wrap(err, "failed to parse primitive type")
		}
		*pt = PrimitiveTypes{t}
		return nil
	case []interface{}:
		*pt = make(PrimitiveTypes, len(val))
		for i, ts := range val {
			s, ok := ts.(string)
			if !ok {
				return errors.Wrap(
					errInvalidType("string", ts),
					"failed to extract type",
				)
			}
			t, err := primitiveFromString(s)
			if err != nil {
				return errors.Wrap(err, "failed to parse primitive type")
			}
			(*pt)[i] = t
		}
		return nil
	default:
		return errors.Wrap(
			errInvalidType("[]string or string", v),
			"failed to extract 'type'",
		)
	}
}
func (dm *DependencyMap) extract(m map[string]interface{}) error {
	dm.Names = make(map[string][]string)
	dm.Schemas = make(map[string]*Schema)
	for k, p := range m {
		switch val := p.(type) {
		case []interface{}:
			var l []string
			if err := convertStringList(&l, val); err != nil {
				return err
			}
			dm.Names[k] = l
		case map[string]interface{}:
			s := New()
			if err := s.Extract(val); err != nil {
				return err
			}
			dm.Schemas[k] = s
		default:
			return errors.Wrap(
				errInvalidType("[]interface{} or map[string]interface{}", p),
				"failed to extract 'type'",
			)
		}
	}
	return nil
}