Fully integrate draft version detection
diff --git a/draft.go b/draft.go
index d01fa53..3f07680 100644
--- a/draft.go
+++ b/draft.go
@@ -1,5 +1,12 @@
 package gojsonschema
 
+import (
+	"errors"
+	"reflect"
+
+	"github.com/xeipuuv/gojsonreference"
+)
+
 type Draft int
 
 const (
@@ -9,15 +16,101 @@
 	Draft7 Draft = 7
 )
 
-var (
-	draftDict = map[Draft]string{
-		Draft4: "http://json-schema.org/draft-04/schema",
-		Draft6: "http://json-schema.org/draft-06/schema",
-		Draft7: "http://json-schema.org/draft-07/schema",
+type draftConfig struct {
+	Version       Draft
+	MetaSchemaURL string
+	MetaSchema    string
+}
+type draftConfigs []draftConfig
+
+var drafts draftConfigs
+
+func init() {
+	drafts = []draftConfig{
+		draftConfig{
+			Version:       Draft4,
+			MetaSchemaURL: "http://json-schema.org/draft-04/schema",
+			MetaSchema:    `{"id":"http://json-schema.org/draft-04/schema#","$schema":"http://json-schema.org/draft-04/schema#","description":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"positiveInteger":{"type":"integer","minimum":0},"positiveIntegerDefault0":{"allOf":[{"$ref":"#/definitions/positiveInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"minItems":1,"uniqueItems":true}},"type":"object","properties":{"id":{"type":"string"},"$schema":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"multipleOf":{"type":"number","minimum":0,"exclusiveMinimum":true},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"boolean","default":false},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"boolean","default":false},"maxLength":{"$ref":"#/definitions/positiveInteger"},"minLength":{"$ref":"#/definitions/positiveIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/positiveInteger"},"minItems":{"$ref":"#/definitions/positiveIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxProperties":{"$ref":"#/definitions/positiveInteger"},"minProperties":{"$ref":"#/definitions/positiveIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"dependencies":{"exclusiveMaximum":["maximum"],"exclusiveMinimum":["minimum"]},"default":{}}`,
+		},
+		draftConfig{
+			Version:       Draft6,
+			MetaSchemaURL: "http://json-schema.org/draft-06/schema",
+			MetaSchema:    `{"$schema":"http://json-schema.org/draft-06/schema#","$id":"http://json-schema.org/draft-06/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"examples":{"type":"array","items":{}},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":{},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":{}}`,
+		},
+		draftConfig{
+			Version:       Draft7,
+			MetaSchemaURL: "http://json-schema.org/draft-07/schema",
+			MetaSchema:    `{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}`,
+		},
 	}
-	schemaDict = map[string]Draft{
-		"http://json-schema.org/draft-04/schema": Draft4,
-		"http://json-schema.org/draft-06/schema": Draft6,
-		"http://json-schema.org/draft-07/schema": Draft7,
+}
+
+func (dc draftConfigs) GetMetaSchema(url string) string {
+	for _, config := range dc {
+		if config.MetaSchemaURL == url {
+			return config.MetaSchema
+		}
 	}
-)
+	return ""
+}
+func (dc draftConfigs) GetDraftVersion(url string) *Draft {
+	for _, config := range dc {
+		if config.MetaSchemaURL == url {
+			return &config.Version
+		}
+	}
+	return nil
+}
+func (dc draftConfigs) GetSchemaURL(draft Draft) string {
+	for _, config := range dc {
+		if config.Version == draft {
+			return config.MetaSchemaURL
+		}
+	}
+	return ""
+}
+
+func parseSchemaURL(documentNode interface{}) (string, *Draft, error) {
+
+	if isKind(documentNode, reflect.Bool) {
+		return "", nil, nil
+	}
+	m := documentNode.(map[string]interface{})
+
+	if existsMapKey(m, KEY_SCHEMA) {
+		if !isKind(m[KEY_SCHEMA], reflect.String) {
+			return "", nil, errors.New(formatErrorDescription(
+				Locale.MustBeOfType(),
+				ErrorDetails{
+					"key":  KEY_SCHEMA,
+					"type": TYPE_STRING,
+				},
+			))
+		}
+
+		schemaReference, err := gojsonreference.NewJsonReference(m[KEY_SCHEMA].(string))
+
+		if err != nil {
+			return "", nil, err
+		}
+
+		schema := schemaReference.String()
+
+		return schema, drafts.GetDraftVersion(schema), nil
+	}
+
+	return "", nil, nil
+}
+
+// var (
+// 	draftDict = map[Draft]string{
+// 		Draft4: "http://json-schema.org/draft-04/schema",
+// 		Draft6: "http://json-schema.org/draft-06/schema",
+// 		Draft7: "http://json-schema.org/draft-07/schema",
+// 	}
+// 	schemaDict = map[string]Draft{
+// 		"http://json-schema.org/draft-04/schema": Draft4,
+// 		"http://json-schema.org/draft-06/schema": Draft6,
+// 		"http://json-schema.org/draft-07/schema": Draft7,
+// 	}
+// )
diff --git a/jsonLoader.go b/jsonLoader.go
index 8dd0b69..cfa5f6a 100644
--- a/jsonLoader.go
+++ b/jsonLoader.go
@@ -166,32 +166,28 @@
 
 func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) {
 
-	switch address {
-	case "http://json-schema.org/draft-04/schema":
-		return decodeJsonUsingNumber(strings.NewReader(`{"id":"http://json-schema.org/draft-04/schema#","$schema":"http://json-schema.org/draft-04/schema#","description":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"positiveInteger":{"type":"integer","minimum":0},"positiveIntegerDefault0":{"allOf":[{"$ref":"#/definitions/positiveInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"minItems":1,"uniqueItems":true}},"type":"object","properties":{"id":{"type":"string"},"$schema":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"multipleOf":{"type":"number","minimum":0,"exclusiveMinimum":true},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"boolean","default":false},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"boolean","default":false},"maxLength":{"$ref":"#/definitions/positiveInteger"},"minLength":{"$ref":"#/definitions/positiveIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/positiveInteger"},"minItems":{"$ref":"#/definitions/positiveIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxProperties":{"$ref":"#/definitions/positiveInteger"},"minProperties":{"$ref":"#/definitions/positiveIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"dependencies":{"exclusiveMaximum":["maximum"],"exclusiveMinimum":["minimum"]},"default":{}}`))
-	case "http://json-schema.org/draft-06/schema":
-		return decodeJsonUsingNumber(strings.NewReader(`{"$schema":"http://json-schema.org/draft-06/schema#","$id":"http://json-schema.org/draft-06/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"examples":{"type":"array","items":{}},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":{},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":{}}`))
-	case "http://json-schema.org/draft-07/schema":
-		return decodeJsonUsingNumber(strings.NewReader(`{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}`))
-	default:
-
-		resp, err := http.Get(address)
-		if err != nil {
-			return nil, err
-		}
-
-		// must return HTTP Status 200 OK
-		if resp.StatusCode != http.StatusOK {
-			return nil, errors.New(formatErrorDescription(Locale.HttpBadStatus(), ErrorDetails{"status": resp.Status}))
-		}
-
-		bodyBuff, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			return nil, err
-		}
-
-		return decodeJsonUsingNumber(bytes.NewReader(bodyBuff))
+	// returned cached versions for metaschemas for drafts 4, 6 and 7
+	// for performance and allow for easier offline use
+	if metaSchema := drafts.GetMetaSchema(address); metaSchema != "" {
+		return decodeJsonUsingNumber(strings.NewReader(metaSchema))
 	}
+
+	resp, err := http.Get(address)
+	if err != nil {
+		return nil, err
+	}
+
+	// must return HTTP Status 200 OK
+	if resp.StatusCode != http.StatusOK {
+		return nil, errors.New(formatErrorDescription(Locale.HttpBadStatus(), ErrorDetails{"status": resp.Status}))
+	}
+
+	bodyBuff, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	return decodeJsonUsingNumber(bytes.NewReader(bodyBuff))
 }
 
 func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) {
diff --git a/schema.go b/schema.go
index dfa6242..6ce1315 100644
--- a/schema.go
+++ b/schema.go
@@ -891,6 +891,7 @@
 	newSchema.id = currentSchema.ref
 
 	refdDocumentNode = dsp.Document
+	newSchema.draft = dsp.Draft
 
 	if err != nil {
 		return err
diff --git a/schemaLoader.go b/schemaLoader.go
index 591a6b7..f50f3ae 100644
--- a/schemaLoader.go
+++ b/schemaLoader.go
@@ -3,7 +3,6 @@
 import (
 	"bytes"
 	"errors"
-	"reflect"
 
 	"github.com/xeipuuv/gojsonreference"
 )
@@ -25,45 +24,32 @@
 		Validate:   true,
 		Draft:      Hybrid,
 	}
+	ps.pool.autoDetect = &ps.AutoDetect
 
 	return ps
 }
 
 func (sl *SchemaLoader) validateMetaschema(documentNode interface{}) error {
 
-	if isKind(documentNode, reflect.Bool) {
-		return nil
-	}
-	m := documentNode.(map[string]interface{})
-
-	var schema string
-	if existsMapKey(m, KEY_SCHEMA) {
-		if !isKind(m[KEY_SCHEMA], reflect.String) {
-			return errors.New(formatErrorDescription(
-				Locale.MustBeOfType(),
-				ErrorDetails{
-					"key":  KEY_SCHEMA,
-					"type": TYPE_STRING,
-				},
-			))
-		}
-
-		schemaReference, err := gojsonreference.NewJsonReference(m[KEY_SCHEMA].(string))
+	var (
+		schema string
+		draft  *Draft
+		err    error
+	)
+	if sl.AutoDetect {
+		schema, draft, err = parseSchemaURL(documentNode)
 		if err != nil {
 			return err
 		}
-		schema = schemaReference.String()
-		if sl.AutoDetect {
-			if s, ok := schemaDict[schema]; ok {
-				sl.Draft = s
-			}
+		if draft != nil {
+			sl.Draft = *draft
 		}
 	}
 	if sl.Draft == Hybrid {
 		return nil
 	}
 	if schema == "" {
-		schema = draftDict[sl.Draft]
+		schema = drafts.GetSchemaURL(sl.Draft)
 	}
 
 	//Disable validation when loading the metaschema to prevent an infinite recursive loop
@@ -111,7 +97,7 @@
 
 		// Directly use the Recursive function, so that it get only added to the schema pool by $id
 		// and not by the ref of the document as it's empty
-		if err = sl.pool.parseReferencesRecursive(doc, emptyRef); err != nil {
+		if err = sl.pool.parseReferences(doc, emptyRef, false); err != nil {
 			return err
 		}
 	}
@@ -140,7 +126,7 @@
 		}
 	}
 
-	return sl.pool.ParseReferences(doc, ref)
+	return sl.pool.parseReferences(doc, ref, true)
 }
 
 func (sl *SchemaLoader) Compile(rootSchema JSONLoader) (*Schema, error) {
@@ -173,7 +159,7 @@
 		}
 		// References need only be parsed if loading JSON directly
 		//  as pool.GetDocument already does this for us if loading by reference
-		err = d.pool.ParseReferences(doc, ref)
+		err = sl.pool.parseReferences(doc, ref, true)
 		if err != nil {
 			return nil, err
 		}
diff --git a/schemaPool.go b/schemaPool.go
index 6cce02c..f124e03 100644
--- a/schemaPool.go
+++ b/schemaPool.go
@@ -36,34 +36,44 @@
 
 type schemaPoolDocument struct {
 	Document interface{}
-	Draft    Draft
+	Draft    *Draft
 }
 
 type schemaPool struct {
 	schemaPoolDocuments map[string]*schemaPoolDocument
 	jsonLoaderFactory   JSONLoaderFactory
+	autoDetect          *bool
 }
 
-func newSchemaPool(f JSONLoaderFactory) *schemaPool {
+func (p *schemaPool) parseReferences(document interface{}, ref gojsonreference.JsonReference, pooled bool) error {
 
-	p := &schemaPool{}
-	p.schemaPoolDocuments = make(map[string]*schemaPoolDocument)
-	p.jsonLoaderFactory = f
-
-	return p
-}
-
-func (p *schemaPool) ParseReferences(document interface{}, ref gojsonreference.JsonReference) error {
-	// Only the root document should be added to the schema pool
-	if _, ok := p.schemaPoolDocuments[ref.String()]; ok {
-		return fmt.Errorf("Reference already exists: \"%s\"", ref.String())
+	var (
+		draft     *Draft
+		err       error
+		reference = ref.String()
+	)
+	// Only the root document should be added to the schema pool if pooled is true
+	if _, ok := p.schemaPoolDocuments[reference]; pooled && ok {
+		return fmt.Errorf("Reference already exists: \"%s\"", reference)
 	}
-	err := p.parseReferencesRecursive(document, ref)
-	p.schemaPoolDocuments[ref.String()] = &schemaPoolDocument{Document: document}
+
+	if *p.autoDetect {
+		_, draft, err = parseSchemaURL(document)
+		if err != nil {
+			return err
+		}
+	}
+
+	err = p.parseReferencesRecursive(document, ref, draft)
+
+	if pooled {
+		p.schemaPoolDocuments[reference] = &schemaPoolDocument{Document: document, Draft: draft}
+	}
+
 	return err
 }
 
-func (p *schemaPool) parseReferencesRecursive(document interface{}, ref gojsonreference.JsonReference) error {
+func (p *schemaPool) parseReferencesRecursive(document interface{}, ref gojsonreference.JsonReference, draft *Draft) error {
 	// parseReferencesRecursive parses a JSON document and resolves all $id and $ref references.
 	// For $ref references it takes into account the $id scope it is in and replaces
 	// the reference by the absolute resolved reference
@@ -73,7 +83,7 @@
 	switch m := document.(type) {
 	case []interface{}:
 		for _, v := range m {
-			p.parseReferencesRecursive(v, ref)
+			p.parseReferencesRecursive(v, ref, draft)
 		}
 	case map[string]interface{}:
 		localRef := &ref
@@ -90,7 +100,7 @@
 					if _, ok := p.schemaPoolDocuments[localRef.String()]; ok {
 						return fmt.Errorf("Reference already exists: \"%s\"", localRef.String())
 					}
-					p.schemaPoolDocuments[localRef.String()] = &schemaPoolDocument{Document: document}
+					p.schemaPoolDocuments[localRef.String()] = &schemaPoolDocument{Document: document, Draft: draft}
 				}
 			}
 		}
@@ -115,11 +125,11 @@
 			if k == KEY_PROPERTIES || k == KEY_DEPENDENCIES || k == KEY_PATTERN_PROPERTIES {
 				if child, ok := v.(map[string]interface{}); ok {
 					for _, v := range child {
-						p.parseReferencesRecursive(v, *localRef)
+						p.parseReferencesRecursive(v, *localRef, draft)
 					}
 				}
 			} else {
-				p.parseReferencesRecursive(v, *localRef)
+				p.parseReferencesRecursive(v, *localRef, draft)
 			}
 		}
 	}
@@ -129,9 +139,10 @@
 func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*schemaPoolDocument, error) {
 
 	var (
-		spd *schemaPoolDocument
-		ok  bool
-		err error
+		spd   *schemaPoolDocument
+		draft *Draft
+		ok    bool
+		err   error
 	)
 
 	if internalLogEnabled {
@@ -189,7 +200,9 @@
 	}
 
 	// add the whole document to the pool for potential re-use
-	p.ParseReferences(document, refToUrl)
+	p.parseReferences(document, refToUrl, true)
+
+	_, draft, _ = parseSchemaURL(document)
 
 	// resolve the potential fragment and also cache it
 	document, _, err = reference.GetPointer().Get(document)
@@ -198,5 +211,5 @@
 		return nil, err
 	}
 
-	return &schemaPoolDocument{Document: document}, nil
+	return &schemaPoolDocument{Document: document, Draft: draft}, nil
 }