Make JSONLoader public to support cusotm json loader
diff --git a/jsonLoader.go b/jsonLoader.go
index 0b40574..085efe7 100644
--- a/jsonLoader.go
+++ b/jsonLoader.go
@@ -46,11 +46,38 @@
 // JSON loader interface
 
 type JSONLoader interface {
-	jsonSource() interface{}
-	loadJSON() (interface{}, error)
-	loadSchema() (*Schema, error)
+	JsonSource() interface{}
+	LoadJSON() (interface{}, error)
+	JsonReference() (gojsonreference.JsonReference, error)
+	LoaderFactory() JSONLoaderFactory
 }
 
+type JSONLoaderFactory interface {
+	New(source string) JSONLoader
+}
+
+type DefaultJSONLoaderFactory struct {
+}
+
+type FileSystemJSONLoaderFactory struct {
+	fs http.FileSystem
+}
+
+func (d DefaultJSONLoaderFactory) New(source string) JSONLoader {
+	return &jsonReferenceLoader{
+		fs:     osFS,
+		source: source,
+	}
+}
+
+func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader {
+	return &jsonReferenceLoader{
+		fs:     f.fs,
+		source: source,
+	}
+}
+
+
 // osFileSystem is a functional wrapper for os.Open that implements http.FileSystem.
 type osFileSystem func(string) (*os.File, error)
 
@@ -66,10 +93,18 @@
 	source string
 }
 
-func (l *jsonReferenceLoader) jsonSource() interface{} {
+func (l *jsonReferenceLoader) JsonSource() interface{} {
 	return l.source
 }
 
+func (l *jsonReferenceLoader) JsonReference() (gojsonreference.JsonReference, error) {
+	return gojsonreference.NewJsonReference(l.JsonSource().(string))
+}
+
+func (l *jsonReferenceLoader) LoaderFactory() JSONLoaderFactory {
+	return &DefaultJSONLoaderFactory{}
+}
+
 // NewReferenceLoader returns a JSON reference loader using the given source and the local OS file system.
 func NewReferenceLoader(source string) *jsonReferenceLoader {
 	return &jsonReferenceLoader{
@@ -86,11 +121,11 @@
 	}
 }
 
-func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {
+func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) {
 
 	var err error
 
-	reference, err := gojsonreference.NewJsonReference(l.jsonSource().(string))
+	reference, err := gojsonreference.NewJsonReference(l.JsonSource().(string))
 	if err != nil {
 		return nil, err
 	}
@@ -131,32 +166,6 @@
 
 }
 
-func (l *jsonReferenceLoader) loadSchema() (*Schema, error) {
-
-	var err error
-
-	d := Schema{}
-	d.pool = newSchemaPool(l.fs)
-	d.referencePool = newSchemaReferencePool()
-
-	d.documentReference, err = gojsonreference.NewJsonReference(l.jsonSource().(string))
-	if err != nil {
-		return nil, err
-	}
-
-	spd, err := d.pool.GetDocument(d.documentReference)
-	if err != nil {
-		return nil, err
-	}
-
-	err = d.parse(spd.Document)
-	if err != nil {
-		return nil, err
-	}
-
-	return &d, nil
-
-}
 
 func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) {
 
@@ -201,44 +210,25 @@
 	source string
 }
 
-func (l *jsonStringLoader) jsonSource() interface{} {
+func (l *jsonStringLoader) JsonSource() interface{} {
 	return l.source
 }
 
+func (l *jsonStringLoader) JsonReference() (gojsonreference.JsonReference, error) {
+	return gojsonreference.NewJsonReference("#")
+}
+
+func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory {
+	return &DefaultJSONLoaderFactory{}
+}
+
 func NewStringLoader(source string) *jsonStringLoader {
 	return &jsonStringLoader{source: source}
 }
 
-func (l *jsonStringLoader) loadJSON() (interface{}, error) {
+func (l *jsonStringLoader) LoadJSON() (interface{}, error) {
 
-	return decodeJsonUsingNumber(strings.NewReader(l.jsonSource().(string)))
-
-}
-
-func (l *jsonStringLoader) loadSchema() (*Schema, error) {
-
-	var err error
-
-	document, err := l.loadJSON()
-	if err != nil {
-		return nil, err
-	}
-
-	d := Schema{}
-	d.pool = newSchemaPool(osFS)
-	d.referencePool = newSchemaReferencePool()
-	d.documentReference, err = gojsonreference.NewJsonReference("#")
-	d.pool.SetStandaloneDocument(document)
-	if err != nil {
-		return nil, err
-	}
-
-	err = d.parse(document)
-	if err != nil {
-		return nil, err
-	}
-
-	return &d, nil
+	return decodeJsonUsingNumber(strings.NewReader(l.JsonSource().(string)))
 
 }
 
@@ -249,19 +239,27 @@
 	source interface{}
 }
 
-func (l *jsonGoLoader) jsonSource() interface{} {
+func (l *jsonGoLoader) JsonSource() interface{} {
 	return l.source
 }
 
+func (l *jsonGoLoader) JsonReference() (gojsonreference.JsonReference, error) {
+	return gojsonreference.NewJsonReference("#")
+}
+
+func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory {
+	return &DefaultJSONLoaderFactory{}
+}
+
 func NewGoLoader(source interface{}) *jsonGoLoader {
 	return &jsonGoLoader{source: source}
 }
 
-func (l *jsonGoLoader) loadJSON() (interface{}, error) {
+func (l *jsonGoLoader) LoadJSON() (interface{}, error) {
 
 	// convert it to a compliant JSON first to avoid types "mismatches"
 
-	jsonBytes, err := json.Marshal(l.jsonSource())
+	jsonBytes, err := json.Marshal(l.JsonSource())
 	if err != nil {
 		return nil, err
 	}
@@ -270,33 +268,6 @@
 
 }
 
-func (l *jsonGoLoader) loadSchema() (*Schema, error) {
-
-	var err error
-
-	document, err := l.loadJSON()
-	if err != nil {
-		return nil, err
-	}
-
-	d := Schema{}
-	d.pool = newSchemaPool(osFS)
-	d.referencePool = newSchemaReferencePool()
-	d.documentReference, err = gojsonreference.NewJsonReference("#")
-	d.pool.SetStandaloneDocument(document)
-	if err != nil {
-		return nil, err
-	}
-
-	err = d.parse(document)
-	if err != nil {
-		return nil, err
-	}
-
-	return &d, nil
-
-}
-
 func decodeJsonUsingNumber(r io.Reader) (interface{}, error) {
 
 	var document interface{}
diff --git a/schema.go b/schema.go
index 577c786..6f60147 100644
--- a/schema.go
+++ b/schema.go
@@ -42,7 +42,39 @@
 )
 
 func NewSchema(l JSONLoader) (*Schema, error) {
-	return l.loadSchema()
+	ref, err := l.JsonReference()
+	if err != nil {
+		return nil, err
+	}
+
+	d := Schema{}
+	d.pool = newSchemaPool(l.LoaderFactory())
+	d.documentReference = ref
+	d.referencePool=newSchemaReferencePool()
+
+	var doc interface{}
+	if ref.String() != "#" {
+		// Get document from schema pool
+		spd, err := d.pool.GetDocument(d.documentReference)
+		if err != nil {
+			return nil, err
+		}
+		doc = spd.Document
+	} else {
+		// Load JSON directly
+		doc, err = l.LoadJSON()
+		if err != nil {
+			return nil, err
+		}
+		d.pool.SetStandaloneDocument(doc)
+	}
+
+	err = d.parse(doc)
+	if err != nil {
+		return nil, err
+	}
+
+	return &d, nil
 }
 
 type Schema struct {
diff --git a/schemaPool.go b/schemaPool.go
index 70ae731..f2ad641 100644
--- a/schemaPool.go
+++ b/schemaPool.go
@@ -28,7 +28,6 @@
 
 import (
 	"errors"
-	"net/http"
 
 	"github.com/xeipuuv/gojsonreference"
 )
@@ -40,15 +39,15 @@
 type schemaPool struct {
 	schemaPoolDocuments map[string]*schemaPoolDocument
 	standaloneDocument  interface{}
-	fs                  http.FileSystem
+	jsonLoaderFactory   JSONLoaderFactory
 }
 
-func newSchemaPool(fs http.FileSystem) *schemaPool {
+func newSchemaPool(f JSONLoaderFactory) *schemaPool {
 
 	p := &schemaPool{}
 	p.schemaPoolDocuments = make(map[string]*schemaPoolDocument)
 	p.standaloneDocument = nil
-	p.fs = fs
+	p.jsonLoaderFactory = f
 
 	return p
 }
@@ -96,8 +95,8 @@
 		return spd, nil
 	}
 
-	jsonReferenceLoader := NewReferenceLoaderFileSystem(reference.String(), p.fs)
-	document, err := jsonReferenceLoader.loadJSON()
+	jsonReferenceLoader := p.jsonLoaderFactory.New(reference.String())
+	document, err := jsonReferenceLoader.LoadJSON()
 	if err != nil {
 		return nil, err
 	}
diff --git a/validation.go b/validation.go
index 2dc0df2..60d637e 100644
--- a/validation.go
+++ b/validation.go
@@ -55,7 +55,7 @@
 
 	// load document
 
-	root, err := l.loadJSON()
+	root, err := l.LoadJSON()
 	if err != nil {
 		return nil, err
 	}