Implement id parsing in conjuction with $ref fixes
diff --git a/schema.go b/schema.go
index 2cac71e..55cb1cf 100644
--- a/schema.go
+++ b/schema.go
@@ -27,7 +27,6 @@
 package gojsonschema
 
 import (
-	//	"encoding/json"
 	"errors"
 	"reflect"
 	"regexp"
@@ -56,10 +55,11 @@
 	d.documentReference = ref
 	d.referencePool = newSchemaReferencePool()
 
+	var spd *schemaPoolDocument
 	var doc interface{}
 	if ref.String() != "" {
 		// Get document from schema pool
-		spd, err := d.pool.GetDocument(d.documentReference)
+		spd, err = d.pool.GetDocument(d.documentReference)
 		if err != nil {
 			return nil, err
 		}
@@ -70,8 +70,8 @@
 		if err != nil {
 			return nil, err
 		}
-		d.pool.SetStandaloneDocument(doc)
 	}
+	d.pool.SetStandaloneDocument(doc)
 
 	err = d.parse(doc)
 	if err != nil {
@@ -113,12 +113,48 @@
 			},
 		))
 	}
+	if currentSchema.parent == nil {
+		currentSchema.ref = &d.documentReference
+		currentSchema.id = &d.documentReference
+	}
+
+	if currentSchema.id == nil && currentSchema.parent != nil {
+		currentSchema.id = currentSchema.parent.id
+	}
 
 	m := documentNode.(map[string]interface{})
 
-	if currentSchema == d.rootSchema {
-		currentSchema.ref = &d.documentReference
+	// id
+	if existsMapKey(m, KEY_ID) && !isKind(m[KEY_ID], reflect.String) {
+		return errors.New(formatErrorDescription(
+			Locale.InvalidType(),
+			ErrorDetails{
+				"expected": TYPE_STRING,
+				"given":    KEY_ID,
+			},
+		))
 	}
+	if k, ok := m[KEY_ID].(string); ok {
+		jsonReference, err := gojsonreference.NewJsonReference(k)
+		if err != nil {
+			return err
+		}
+		if currentSchema == d.rootSchema {
+			currentSchema.id = &jsonReference
+		} else {
+			ref, err := currentSchema.parent.id.Inherits(jsonReference)
+			if err != nil {
+				return err
+			}
+			currentSchema.id = ref
+		}
+	}
+
+	// Add schema to document cache. The same id is passed down to subsequent
+	// subschemas, but as only the first and top one is used it will always reference
+	// the correct schema. Doing it once here prevents having
+	// to do this same step at every corner case.
+	d.referencePool.Add(currentSchema.id.String(), currentSchema)
 
 	// $subSchema
 	if existsMapKey(m, KEY_SCHEMA) {
@@ -159,19 +195,17 @@
 		if jsonReference.HasFullUrl {
 			currentSchema.ref = &jsonReference
 		} else {
-			inheritedReference, err := currentSchema.ref.Inherits(jsonReference)
+			inheritedReference, err := currentSchema.id.Inherits(jsonReference)
 			if err != nil {
 				return err
 			}
-
 			currentSchema.ref = inheritedReference
 		}
-
-		if sch, ok := d.referencePool.Get(currentSchema.ref.String() + k); ok {
+		if sch, ok := d.referencePool.Get(currentSchema.ref.String()); ok {
 			currentSchema.refSchema = sch
-
 		} else {
-			err := d.parseReference(documentNode, currentSchema, k)
+			err := d.parseReference(documentNode, currentSchema)
+
 			if err != nil {
 				return err
 			}
@@ -186,11 +220,23 @@
 			currentSchema.definitions = make(map[string]*subSchema)
 			for dk, dv := range m[KEY_DEFINITIONS].(map[string]interface{}) {
 				if isKind(dv, reflect.Map) {
-					newSchema := &subSchema{property: KEY_DEFINITIONS, parent: currentSchema, ref: currentSchema.ref}
-					currentSchema.definitions[dk] = newSchema
-					err := d.parseSchema(dv, newSchema)
+
+					ref, err := gojsonreference.NewJsonReference("#/" + KEY_DEFINITIONS + "/" + dk)
 					if err != nil {
-						return errors.New(err.Error())
+						return err
+					}
+
+					newSchemaID, err := currentSchema.id.Inherits(ref)
+					if err != nil {
+						return err
+					}
+					newSchema := &subSchema{property: KEY_DEFINITIONS, parent: currentSchema, id: newSchemaID}
+					currentSchema.definitions[dk] = newSchema
+
+					err = d.parseSchema(dv, newSchema)
+
+					if err != nil {
+						return err
 					}
 				} else {
 					return errors.New(formatErrorDescription(
@@ -214,20 +260,6 @@
 
 	}
 
-	// id
-	if existsMapKey(m, KEY_ID) && !isKind(m[KEY_ID], reflect.String) {
-		return errors.New(formatErrorDescription(
-			Locale.InvalidType(),
-			ErrorDetails{
-				"expected": TYPE_STRING,
-				"given":    KEY_ID,
-			},
-		))
-	}
-	if k, ok := m[KEY_ID].(string); ok {
-		currentSchema.id = &k
-	}
-
 	// title
 	if existsMapKey(m, KEY_TITLE) && !isKind(m[KEY_TITLE], reflect.String) {
 		return errors.New(formatErrorDescription(
@@ -798,26 +830,32 @@
 	return nil
 }
 
-func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema, reference string) error {
-	var refdDocumentNode interface{}
+func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema) error {
+	var (
+		refdDocumentNode interface{}
+		dsp              *schemaPoolDocument
+		err              error
+	)
 	jsonPointer := currentSchema.ref.GetPointer()
 	standaloneDocument := d.pool.GetStandaloneDocument()
 
-	if standaloneDocument != nil {
+	newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref}
 
-		var err error
+	if currentSchema.ref.HasFragmentOnly {
 		refdDocumentNode, _, err = jsonPointer.Get(standaloneDocument)
 		if err != nil {
 			return err
 		}
 
 	} else {
-		dsp, err := d.pool.GetDocument(*currentSchema.ref)
+		dsp, err = d.pool.GetDocument(*currentSchema.ref)
 		if err != nil {
 			return err
 		}
+		newSchema.id = currentSchema.ref
 
 		refdDocumentNode, _, err = jsonPointer.Get(dsp.Document)
+
 		if err != nil {
 			return err
 		}
@@ -833,10 +871,8 @@
 
 	// returns the loaded referenced subSchema for the caller to update its current subSchema
 	newSchemaDocument := refdDocumentNode.(map[string]interface{})
-	newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref}
-	d.referencePool.Add(currentSchema.ref.String()+reference, newSchema)
 
-	err := d.parseSchema(newSchemaDocument, newSchema)
+	err = d.parseSchema(newSchemaDocument, newSchema)
 	if err != nil {
 		return err
 	}
diff --git a/schemaPool.go b/schemaPool.go
index f2ad641..ff9715f 100644
--- a/schemaPool.go
+++ b/schemaPool.go
@@ -62,12 +62,16 @@
 
 func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*schemaPoolDocument, error) {
 
+	var (
+		spd *schemaPoolDocument
+		ok  bool
+		err error
+	)
+
 	if internalLogEnabled {
 		internalLog("Get Document ( %s )", reference.String())
 	}
 
-	var err error
-
 	// It is not possible to load anything that is not canonical...
 	if !reference.IsCanonical() {
 		return nil, errors.New(formatErrorDescription(
@@ -75,20 +79,10 @@
 			ErrorDetails{"reference": reference},
 		))
 	}
-
 	refToUrl := reference
 	refToUrl.GetUrl().Fragment = ""
 
-	var spd *schemaPoolDocument
-
-	// Try to find the requested document in the pool
-	for k := range p.schemaPoolDocuments {
-		if k == refToUrl.String() {
-			spd = p.schemaPoolDocuments[k]
-		}
-	}
-
-	if spd != nil {
+	if spd, ok = p.schemaPoolDocuments[refToUrl.String()]; ok {
 		if internalLogEnabled {
 			internalLog(" From pool")
 		}
diff --git a/schemaReferencePool.go b/schemaReferencePool.go
index 294e36a..6e5e1b5 100644
--- a/schemaReferencePool.go
+++ b/schemaReferencePool.go
@@ -62,6 +62,7 @@
 	if internalLogEnabled {
 		internalLog(fmt.Sprintf("Add Schema Reference %s to pool", ref))
 	}
-
-	p.documents[ref] = sch
+	if _, ok := p.documents[ref]; !ok {
+		p.documents[ref] = sch
+	}
 }
diff --git a/schema_test.go b/schema_test.go
index 453dfb8..9f47e4b 100644
--- a/schema_test.go
+++ b/schema_test.go
@@ -360,12 +360,10 @@
 		{"phase": "format validation", "test": "uri format is invalid", "schema": "format/schema_6.json", "data": "format/data_13.json", "valid": "false", "errors": "format"},
 		{"phase": "format validation", "test": "number format is valid", "schema": "format/schema_7.json", "data": "format/data_29.json", "valid": "true"},
 		{"phase": "format validation", "test": "number format is valid", "schema": "format/schema_7.json", "data": "format/data_30.json", "valid": "false", "errors": "format"},
+		{"phase": "change resolution scope", "test": "changed scope ref valid", "schema": "refRemote/schema_3.json", "data": "refRemote/data_30.json", "valid": "true"},
+		{"phase": "change resolution scope", "test": "changed scope ref invalid", "schema": "refRemote/schema_3.json", "data": "refRemote/data_31.json", "valid": "false", "errors": "invalid_type"},
 	}
 
-	//TODO Pass failed tests : id(s) as scope for references is not implemented yet
-	//map[string]string{"phase": "change resolution scope", "test": "changed scope ref valid", "schema": "refRemote/schema_3.json", "data": "refRemote/data_30.json", "valid": "true"},
-	//map[string]string{"phase": "change resolution scope", "test": "changed scope ref invalid", "schema": "refRemote/schema_3.json", "data": "refRemote/data_31.json", "valid": "false"}}
-
 	// Setup a small http server on localhost:1234 for testing purposes
 
 	wd, err := os.Getwd()
@@ -416,6 +414,9 @@
 		expectedValid, _ := strconv.ParseBool(testJson["valid"])
 		if givenValid != expectedValid {
 			t.Errorf("Test failed : %s :: %s, expects %t, given %t\n", testJson["phase"], testJson["test"], expectedValid, givenValid)
+			for _, e := range result.Errors() {
+				fmt.Println("Error: " + e.Type())
+			}
 		}
 
 		if !givenValid && testJson["errors"] != "" {
diff --git a/subSchema.go b/subSchema.go
index 9ddbb5f..9961d92 100644
--- a/subSchema.go
+++ b/subSchema.go
@@ -36,7 +36,7 @@
 
 const (
 	KEY_SCHEMA                = "$subSchema"
-	KEY_ID                    = "$id"
+	KEY_ID                    = "id"
 	KEY_REF                   = "$ref"
 	KEY_TITLE                 = "title"
 	KEY_DESCRIPTION           = "description"
@@ -73,7 +73,7 @@
 type subSchema struct {
 
 	// basic subSchema meta properties
-	id          *string
+	id          *gojsonreference.JsonReference
 	title       *string
 	description *string