 Being strict, it doesn't support common JSON extensions such as comments.
 */
 public class JSONParser {
-	/**
-	A shortcut for creating a `JSONParser` and having it parse the given data.
-	This is a blocking operation, and will block the calling thread until parsing
-	finishes or throws an error.
-	- Parameter data: The Unicode scalars representing the input JSON data.
-	- Returns: The root `JSON` node from the input data.
-	- Throws: A `JSONParseError` if something failed during parsing.
-	*/
-	public class func parse(data: String.UnicodeScalarView) throws -> JSON {
-		let parser = JSONParser(data: data)
-		return try parser.parse()
-	}
-	
-	/**
-	A shortcut for creating a `JSONParser` and having it parse the given `String`.
-	This is a blocking operation, and will block the calling thread until parsing
-	finishes or throws an error.
-	- Parameter string: The `String` of the input JSON.
-	- Returns: The root `JSON` node from the input data.
-	- Throws: A `JSONParseError` if something failed during parsing.
-	*/
-	public class func parse(string: String) throws -> JSON {
-		let parser = JSONParser(data: string.unicodeScalars)
-		return try parser.parse()
-	}
-	
-	/**
-	Designated initializer for `JSONParser`, which requires an input Unicode scalar
-	collection.
-	- Parameter data: The Unicode scalars representing the input JSON data.
-	*/
-	public init(data: String.UnicodeScalarView) {
-		generator = data.generate()
-		self.data = data
-	}
-	
-	/**
-	Starts parsing the data. This is a blocking operation, and will block the
-	calling thread until parsing finishes or throws an error.
-	- Returns: The root `JSON` node from the input data.
-	- Throws: A `JSONParseError` if something failed during parsing.
-	*/
-	public func parse() throws -> JSON {
-		do {
-			try nextScalar()
-			let value = try nextValue()
-			do {
-				try nextScalar()
-				let v = scalar.value
-				if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-					// Skip to EOF or the next token
-					try skipToNextToken()
-					// If we get this far some token was found ...
-					throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-				} else {
-					// There's some weird character at the end of the file...
-					throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-				}
-			} catch JSONParseError.EndOfFile {
-				return value
-			}
-		} catch JSONParseError.EndOfFile {
-			throw JSONParseError.EmptyInput
-		}
-	}
-	
-	// MARK: - Internals: Properties
-	
-	var generator: String.UnicodeScalarView.Generator
-	let data: String.UnicodeScalarView
-	var scalar: UnicodeScalar!
-	var lineNumber: UInt = 0
-	var charNumber: UInt = 0
-	
-	var crlfHack = false
-	
+    /**
+    A shortcut for creating a `JSONParser` and having it parse the given data.
+    This is a blocking operation, and will block the calling thread until parsing
+    finishes or throws an error.
+    - Parameter data: The Unicode scalars representing the input JSON data.
+    - Returns: The root `JSON` node from the input data.
+    - Throws: A `JSONParseError` if something failed during parsing.
+    */
+    public class func parse(data: String.UnicodeScalarView) throws -> JSON {
+        let parser = JSONParser(data: data)
+        return try parser.parse()
+    }
+
+    /**
+    A shortcut for creating a `JSONParser` and having it parse the given `String`.
+    This is a blocking operation, and will block the calling thread until parsing
+    finishes or throws an error.
+    - Parameter string: The `String` of the input JSON.
+    - Returns: The root `JSON` node from the input data.
+    - Throws: A `JSONParseError` if something failed during parsing.
+    */
+    public class func parse(string: String) throws -> JSON {
+        let parser = JSONParser(data: string.unicodeScalars)
+        return try parser.parse()
+    }
+
+    /**
+    Designated initializer for `JSONParser`, which requires an input Unicode scalar
+    collection.
+    - Parameter data: The Unicode scalars representing the input JSON data.
+    */
+    public init(data: String.UnicodeScalarView) {
+        generator = data.generate()
+        self.data = data
+    }
+
+    /**
+    Starts parsing the data. This is a blocking operation, and will block the
+    calling thread until parsing finishes or throws an error.
+    - Returns: The root `JSON` node from the input data.
+    - Throws: A `JSONParseError` if something failed during parsing.
+    */
+    public func parse() throws -> JSON {
+        do {
+            try nextScalar()
+            let value = try nextValue()
+            do {
+                try nextScalar()
+                let v = scalar.value
+                if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+                    // Skip to EOF or the next token
+                    try skipToNextToken()
+                    // If we get this far some token was found ...
+                    throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                } else {
+                    // There's some weird character at the end of the file...
+                    throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                }
+            } catch JSONParseError.EndOfFile {
+                return value
+            }
+        } catch JSONParseError.EndOfFile {
+            throw JSONParseError.EmptyInput
+        }
+    }
+
+    // MARK: - Internals: Properties
+
+    var generator: String.UnicodeScalarView.Generator
+    let data: String.UnicodeScalarView
+    var scalar: UnicodeScalar!
+    var lineNumber: UInt = 0
+    var charNumber: UInt = 0
+
+    var crlfHack = false
+
 }
 
 // MARK: JSONParser Internals
 extension JSONParser {
-	// MARK: - Enumerating the scalar collection
-	func nextScalar() throws {
-		if let sc = generator.next() {
-			scalar = sc
-			charNumber = charNumber + 1
-			if crlfHack == true && sc != lineFeed {
-				crlfHack = false
-			}
-		} else {
-			throw JSONParseError.EndOfFile
-		}
-	}
-	
-	func skipToNextToken() throws {
-		var v = scalar.value
-		if v != 0x0009 && v != 0x000A && v != 0x000D && v != 0x0020 {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		
-		while v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-			if scalar == carriageReturn || scalar == lineFeed {
-				if crlfHack == true && scalar == lineFeed {
-					crlfHack = false
-					charNumber = 0
-				} else {
-					if (scalar == carriageReturn) {
-						crlfHack = true
-					}
-					lineNumber = lineNumber + 1
-					charNumber = 0
-				}
-			}
-			try nextScalar()
-			v = scalar.value
-		}
-	}
-	
-	func nextScalars(count: UInt) throws -> [UnicodeScalar] {
-		var values = [UnicodeScalar]()
-		values.reserveCapacity(Int(count))
-		for _ in 0..<count {
-			try nextScalar()
-			values.append(scalar)
-		}
-		return values
-	}
-	
-	// MARK: - Parse loop
-	func nextValue() throws -> JSON {
-		let v = scalar.value
-		if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-			try skipToNextToken()
-		}
-		switch scalar {
-		case leftCurlyBracket:
-			return try nextObject()
-		case leftSquareBracket:
-			return try nextArray()
-		case quotationMark:
-			return try nextString()
-		case trueToken[0], falseToken[0]:
-			return try nextBool()
-		case nullToken[0]:
-			return try nextNull()
-		case "0".unicodeScalars.first!..."9".unicodeScalars.first!,negativeScalar,decimalScalar:
-			return try nextNumber()
-		default:
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-	}
-	
-	// MARK: - Parse a specific, expected type
-	func nextObject() throws -> JSON {
-		if scalar != leftCurlyBracket {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		var dictBuilder = [String : JSON]()
-		try nextScalar()
-		if scalar == rightCurlyBracket {
-			// Empty object
-			return JSON.object(dictBuilder)
-		}
-		outerLoop: repeat {
-			var v = scalar.value
-			if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-				try skipToNextToken()
-			}
-			let string = try nextString()
-			try nextScalar() // Skip the quotation character
-			v = scalar.value
-			if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-				try skipToNextToken()
-			}
-			if scalar != colon {
-				throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-			}
-			try nextScalar() // Skip the ':'
-			let value = try nextValue()
-			switch value {
-			// Skip the closing character for all values except number, which doesn't have one
-			case .integer, .double:
-				break
-			default:
-				try nextScalar()
-			}
-			v = scalar.value
-			if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-				try skipToNextToken()
-			}
-			guard case .string(let key) = string else { throw JSONParseError.Unknown }
-			//let key = string.string! // We're pretty confident it's a string since we called nextString() above
-			dictBuilder[key] = value
-			switch scalar {
-			case rightCurlyBracket:
-				break outerLoop
-			case comma:
-				try nextScalar()
-			default:
-				throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-			}
-			
-		} while true
-		return JSON.object(dictBuilder)
-	}
-	
-	func nextArray() throws -> JSON {
-		if scalar != leftSquareBracket {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		var arrBuilder = [JSON]()
-		try nextScalar()
-		if scalar == rightSquareBracket {
-			// Empty array
-			return JSON.array(arrBuilder)
-		}
-		outerLoop: repeat {
-			let value = try nextValue()
-			arrBuilder.append(value)
-			switch value {
-			// Skip the closing character for all values except number, which doesn't have one
-			case .integer, .double:
-				break
-			default:
-				try nextScalar()
-			}
-			let v = scalar.value
-			if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
-				try skipToNextToken()
-			}
-			switch scalar {
-			case rightSquareBracket:
-				break outerLoop
-			case comma:
-				try nextScalar()
-			default:
-				throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-			}
-		} while true
-		
-		return JSON.array(arrBuilder)
-	}
-	
-	func nextString() throws -> JSON {
-		if scalar != quotationMark {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		try nextScalar() // Skip pas the quotation character
-		var strBuilder = ""
-		var escaping = false
-		outerLoop: repeat {
-			// First we should deal with the escape character and the terminating quote
-			switch scalar {
-			case reverseSolidus:
-				// Escape character
-				if escaping {
-					// Escaping the escape char
-					strBuilder.append(reverseSolidus)
-				}
-				escaping = !escaping
-				try nextScalar()
-			case quotationMark:
-				if escaping {
-					strBuilder.append(quotationMark)
-					escaping = false
-					try nextScalar()
-				} else {
-					break outerLoop
-				}
-			default:
-				// Now the rest
-				if escaping {
-					// Handle all the different escape characters
-					if let s = escapeMap[scalar] {
-						strBuilder.append(s)
-						try nextScalar()
-					} else if scalar == "u".unicodeScalars.first! {
-						let escapedUnicodeValue = try nextUnicodeEscape()
-						strBuilder.append(UnicodeScalar(escapedUnicodeValue))
-						try nextScalar()
-					}
-					escaping = false
-				} else {
-					// Simple append
-					strBuilder.append(scalar)
-					try nextScalar()
-				}
-			}
-		} while true
-		return JSON.string(strBuilder)
-	}
-	
-	func nextUnicodeEscape() throws -> UInt32 {
-		if scalar != "u".unicodeScalars.first! {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		var readScalar = UInt32(0)
-		for _ in 0...3 {
-			readScalar = readScalar * 16
-			try nextScalar()
-			if ("0".unicodeScalars.first!..."9".unicodeScalars.first!).contains(scalar) {
-				readScalar = readScalar + UInt32(scalar.value - "0".unicodeScalars.first!.value)
-			} else if ("a".unicodeScalars.first!..."f".unicodeScalars.first!).contains(scalar) {
-				let aScalarVal = "a".unicodeScalars.first!.value
-				let hexVal = scalar.value - aScalarVal
-				let hexScalarVal = hexVal + 10
-				readScalar = readScalar + hexScalarVal
-			} else if ("A".unicodeScalars.first!..."F".unicodeScalars.first!).contains(scalar) {
-				let aScalarVal = "A".unicodeScalars.first!.value
-				let hexVal = scalar.value - aScalarVal
-				let hexScalarVal = hexVal + 10
-				readScalar = readScalar + hexScalarVal
-			} else {
-				throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-			}
-		}
-		if readScalar >= 0xD800 && readScalar <= 0xDBFF {
-			// UTF-16 surrogate pair
-			// The next character MUST be the other half of the surrogate pair
-			// Otherwise it's a unicode error
-			do {
-				try nextScalar()
-				if scalar != reverseSolidus {
-					throw JSONParseError.InvalidUnicode
-				}
-				try nextScalar()
-				let secondScalar = try nextUnicodeEscape()
-				if secondScalar < 0xDC00 || secondScalar > 0xDFFF {
-					throw JSONParseError.InvalidUnicode
-				}
-				let actualScalar = ((readScalar - 0xD800) * 0x400) + ((secondScalar - 0xDC00) + 0x10000)
-				return actualScalar
-			} catch JSONParseError.UnexpectedCharacter {
-				throw JSONParseError.InvalidUnicode
-			}
-		}
-		return readScalar
-	}
-	
-	func nextNumber() throws -> JSON {
-		var isNegative = false
-		var hasDecimal = false
-		var hasDigits = false
-		var hasExponent = false
-		var positiveExponent = false
-		var exponent = 0
-		var integer: UInt64 = 0
-		var decimal: Int64 = 0
-		var divisor: Double = 10
-		let lineNumAtStart = lineNumber
-		let charNumAtStart = charNumber
-		
-		do {
-			outerLoop: repeat {
-				switch scalar {
-				case "0".unicodeScalars.first!..."9".unicodeScalars.first!:
-					hasDigits = true
-					if hasDecimal {
-						decimal *= 10
-						decimal += Int64(scalar.value - zeroScalar.value)
-						divisor *= 10
-					} else {
-						integer *= 10
-						integer += UInt64(scalar.value - zeroScalar.value)
-					}
-					try nextScalar()
-				case negativeScalar:
-					if hasDigits || hasDecimal || hasDigits || isNegative {
-						throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-					} else {
-						isNegative = true
-					}
-					try nextScalar()
-				case decimalScalar:
-					if hasDecimal {
-						throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-					} else {
-						hasDecimal = true
-					}
-					try nextScalar()
-				case "e".unicodeScalars.first!,"E".unicodeScalars.first!:
-					if hasExponent {
-						throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-					} else {
-						hasExponent = true
-					}
-					try nextScalar()
-					switch scalar {
-					case "0".unicodeScalars.first!..."9".unicodeScalars.first!:
-						positiveExponent = true
-					case plusScalar:
-						positiveExponent = true
-						try nextScalar()
-					case negativeScalar:
-						positiveExponent = false
-						try nextScalar()
-					default:
-						throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-					}
-					exponentLoop: repeat {
-						if scalar.value >= zeroScalar.value && scalar.value <= "9".unicodeScalars.first!.value {
-							exponent *= 10
-							exponent += Int(scalar.value - zeroScalar.value)
-							try nextScalar()
-						} else {
-							break exponentLoop
-						}
-					} while true
-				default:
-					break outerLoop
-				}
-			} while true
-		} catch JSONParseError.EndOfFile {
-			// This is fine
-		}
-		
-		if !hasDigits {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		
-		let sign = isNegative ? -1 : 1
-		if hasDecimal || hasExponent {
-			divisor /= 10
-			var number = Double(sign) * (Double(integer) + (Double(decimal) / divisor))
-			if hasExponent {
-				if positiveExponent {
-					for _ in 1...exponent {
-						number *= Double(10)
-					}
-				} else {
-					for _ in 1...exponent {
-						number /= Double(10)
-					}
-				}
-			}
-			return JSON.double(number)
-		} else {
-			var number: Int64
-			if isNegative {
-				if integer > UInt64(Int64.max) + 1 {
-					throw JSONParseError.InvalidNumber(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
-				} else if integer == UInt64(Int64.max) + 1 {
-					number = Int64.min
-				} else {
-					number = Int64(integer) * -1
-				}
-			} else {
-				if integer > UInt64(Int64.max) {
-					throw JSONParseError.InvalidNumber(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
-				} else {
-					number = Int64(integer)
-				}
-			}
-			return JSON.integer(JSONInteger(number))
-		}
-	}
-	
-	func nextBool() throws -> JSON {
-		var expectedWord: [UnicodeScalar]
-		var expectedBool: Bool
-		let lineNumAtStart = lineNumber
-		let charNumAtStart = charNumber
-		if scalar == trueToken[0] {
-			expectedWord = trueToken
-			expectedBool = true
-		} else if scalar == falseToken[0] {
-			expectedWord = falseToken
-			expectedBool = false
-		} else {
-			throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
-		}
-		do {
-			let word = try [scalar] + nextScalars(UInt(expectedWord.count - 1))
-			if word != expectedWord {
-				throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
-			}
-		} catch JSONParseError.EndOfFile {
-			throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
-		}
-		return JSON.bool(expectedBool)
-	}
-	
-	func nextNull() throws -> JSON {
-		let word = try [scalar] + nextScalars(3)
-		if word != nullToken {
-			throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumber, characterNumber: charNumber-4)
-		}
-		return JSON.null
-	}
+    // MARK: - Enumerating the scalar collection
+    func nextScalar() throws {
+        if let sc = generator.next() {
+            scalar = sc
+            charNumber = charNumber + 1
+            if crlfHack == true && sc != lineFeed {
+                crlfHack = false
+            }
+        } else {
+            throw JSONParseError.EndOfFile
+        }
+    }
+
+    func skipToNextToken() throws {
+        var v = scalar.value
+        if v != 0x0009 && v != 0x000A && v != 0x000D && v != 0x0020 {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+
+        while v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+            if scalar == carriageReturn || scalar == lineFeed {
+                if crlfHack == true && scalar == lineFeed {
+                    crlfHack = false
+                    charNumber = 0
+                } else {
+                    if (scalar == carriageReturn) {
+                        crlfHack = true
+                    }
+                    lineNumber = lineNumber + 1
+                    charNumber = 0
+                }
+            }
+            try nextScalar()
+            v = scalar.value
+        }
+    }
+
+    func nextScalars(count: UInt) throws -> [UnicodeScalar] {
+        var values = [UnicodeScalar]()
+        values.reserveCapacity(Int(count))
+        for _ in 0..<count {
+            try nextScalar()
+            values.append(scalar)
+        }
+        return values
+    }
+
+    // MARK: - Parse loop
+    func nextValue() throws -> JSON {
+        let v = scalar.value
+        if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+            try skipToNextToken()
+        }
+        switch scalar {
+        case leftCurlyBracket:
+            return try nextObject()
+        case leftSquareBracket:
+            return try nextArray()
+        case quotationMark:
+            return try nextString()
+        case trueToken[0], falseToken[0]:
+            return try nextBool()
+        case nullToken[0]:
+            return try nextNull()
+        case "0".unicodeScalars.first!..."9".unicodeScalars.first!,negativeScalar,decimalScalar:
+            return try nextNumber()
+        default:
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+    }
+
+    // MARK: - Parse a specific, expected type
+    func nextObject() throws -> JSON {
+        if scalar != leftCurlyBracket {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+        var dictBuilder = [String : JSON]()
+        try nextScalar()
+        if scalar == rightCurlyBracket {
+            // Empty object
+            return JSON.object(dictBuilder)
+        }
+        outerLoop: repeat {
+            var v = scalar.value
+            if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+                try skipToNextToken()
+            }
+            let string = try nextString()
+            try nextScalar() // Skip the quotation character
+            v = scalar.value
+            if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+                try skipToNextToken()
+            }
+            if scalar != colon {
+                throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+            }
+            try nextScalar() // Skip the ':'
+            let value = try nextValue()
+            switch value {
+            // Skip the closing character for all values except number, which doesn't have one
+            case .integer, .double:
+                break
+            default:
+                try nextScalar()
+            }
+            v = scalar.value
+            if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+                try skipToNextToken()
+            }
+            guard case .string(let key) = string else { throw JSONParseError.Unknown }
+            //let key = string.string! // We're pretty confident it's a string since we called nextString() above
+            dictBuilder[key] = value
+            switch scalar {
+            case rightCurlyBracket:
+                break outerLoop
+            case comma:
+                try nextScalar()
+            default:
+                throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+            }
+
+        } while true
+        return JSON.object(dictBuilder)
+    }
+
+    func nextArray() throws -> JSON {
+        if scalar != leftSquareBracket {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+        var arrBuilder = [JSON]()
+        try nextScalar()
+        if scalar == rightSquareBracket {
+            // Empty array
+            return JSON.array(arrBuilder)
+        }
+        outerLoop: repeat {
+            let value = try nextValue()
+            arrBuilder.append(value)
+            switch value {
+            // Skip the closing character for all values except number, which doesn't have one
+            case .integer, .double:
+                break
+            default:
+                try nextScalar()
+            }
+            let v = scalar.value
+            if v == 0x0009 || v == 0x000A || v == 0x000D || v == 0x0020 {
+                try skipToNextToken()
+            }
+            switch scalar {
+            case rightSquareBracket:
+                break outerLoop
+            case comma:
+                try nextScalar()
+            default:
+                throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+            }
+        } while true
+
+        return JSON.array(arrBuilder)
+    }
+
+    func nextString() throws -> JSON {
+        if scalar != quotationMark {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+        try nextScalar() // Skip pas the quotation character
+        var strBuilder = ""
+        var escaping = false
+        outerLoop: repeat {
+            // First we should deal with the escape character and the terminating quote
+            switch scalar {
+            case reverseSolidus:
+                // Escape character
+                if escaping {
+                    // Escaping the escape char
+                    strBuilder.append(reverseSolidus)
+                }
+                escaping = !escaping
+                try nextScalar()
+            case quotationMark:
+                if escaping {
+                    strBuilder.append(quotationMark)
+                    escaping = false
+                    try nextScalar()
+                } else {
+                    break outerLoop
+                }
+            default:
+                // Now the rest
+                if escaping {
+                    // Handle all the different escape characters
+                    if let s = escapeMap[scalar] {
+                        strBuilder.append(s)
+                        try nextScalar()
+                    } else if scalar == "u".unicodeScalars.first! {
+                        let escapedUnicodeValue = try nextUnicodeEscape()
+                        strBuilder.append(UnicodeScalar(escapedUnicodeValue))
+                        try nextScalar()
+                    }
+                    escaping = false
+                } else {
+                    // Simple append
+                    strBuilder.append(scalar)
+                    try nextScalar()
+                }
+            }
+        } while true
+        return JSON.string(strBuilder)
+    }
+
+    func nextUnicodeEscape() throws -> UInt32 {
+        if scalar != "u".unicodeScalars.first! {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+        var readScalar = UInt32(0)
+        for _ in 0...3 {
+            readScalar = readScalar * 16
+            try nextScalar()
+            if ("0".unicodeScalars.first!..."9".unicodeScalars.first!).contains(scalar) {
+                readScalar = readScalar + UInt32(scalar.value - "0".unicodeScalars.first!.value)
+            } else if ("a".unicodeScalars.first!..."f".unicodeScalars.first!).contains(scalar) {
+                let aScalarVal = "a".unicodeScalars.first!.value
+                let hexVal = scalar.value - aScalarVal
+                let hexScalarVal = hexVal + 10
+                readScalar = readScalar + hexScalarVal
+            } else if ("A".unicodeScalars.first!..."F".unicodeScalars.first!).contains(scalar) {
+                let aScalarVal = "A".unicodeScalars.first!.value
+                let hexVal = scalar.value - aScalarVal
+                let hexScalarVal = hexVal + 10
+                readScalar = readScalar + hexScalarVal
+            } else {
+                throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+            }
+        }
+        if readScalar >= 0xD800 && readScalar <= 0xDBFF {
+            // UTF-16 surrogate pair
+            // The next character MUST be the other half of the surrogate pair
+            // Otherwise it's a unicode error
+            do {
+                try nextScalar()
+                if scalar != reverseSolidus {
+                    throw JSONParseError.InvalidUnicode
+                }
+                try nextScalar()
+                let secondScalar = try nextUnicodeEscape()
+                if secondScalar < 0xDC00 || secondScalar > 0xDFFF {
+                    throw JSONParseError.InvalidUnicode
+                }
+                let actualScalar = ((readScalar - 0xD800) * 0x400) + ((secondScalar - 0xDC00) + 0x10000)
+                return actualScalar
+            } catch JSONParseError.UnexpectedCharacter {
+                throw JSONParseError.InvalidUnicode
+            }
+        }
+        return readScalar
+    }
+
+    func nextNumber() throws -> JSON {
+        var isNegative = false
+        var hasDecimal = false
+        var hasDigits = false
+        var hasExponent = false
+        var positiveExponent = false
+        var exponent = 0
+        var integer: UInt64 = 0
+        var decimal: Int64 = 0
+        var divisor: Double = 10
+        let lineNumAtStart = lineNumber
+        let charNumAtStart = charNumber
+
+        do {
+            outerLoop: repeat {
+                switch scalar {
+                case "0".unicodeScalars.first!..."9".unicodeScalars.first!:
+                    hasDigits = true
+                    if hasDecimal {
+                        decimal *= 10
+                        decimal += Int64(scalar.value - zeroScalar.value)
+                        divisor *= 10
+                    } else {
+                        integer *= 10
+                        integer += UInt64(scalar.value - zeroScalar.value)
+                    }
+                    try nextScalar()
+                case negativeScalar:
+                    if hasDigits || hasDecimal || hasDigits || isNegative {
+                        throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                    } else {
+                        isNegative = true
+                    }
+                    try nextScalar()
+                case decimalScalar:
+                    if hasDecimal {
+                        throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                    } else {
+                        hasDecimal = true
+                    }
+                    try nextScalar()
+                case "e".unicodeScalars.first!,"E".unicodeScalars.first!:
+                    if hasExponent {
+                        throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                    } else {
+                        hasExponent = true
+                    }
+                    try nextScalar()
+                    switch scalar {
+                    case "0".unicodeScalars.first!..."9".unicodeScalars.first!:
+                        positiveExponent = true
+                    case plusScalar:
+                        positiveExponent = true
+                        try nextScalar()
+                    case negativeScalar:
+                        positiveExponent = false
+                        try nextScalar()
+                    default:
+                        throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+                    }
+                    exponentLoop: repeat {
+                        if scalar.value >= zeroScalar.value && scalar.value <= "9".unicodeScalars.first!.value {
+                            exponent *= 10
+                            exponent += Int(scalar.value - zeroScalar.value)
+                            try nextScalar()
+                        } else {
+                            break exponentLoop
+                        }
+                    } while true
+                default:
+                    break outerLoop
+                }
+            } while true
+        } catch JSONParseError.EndOfFile {
+            // This is fine
+        }
+
+        if !hasDigits {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+
+        let sign = isNegative ? -1 : 1
+        if hasDecimal || hasExponent {
+            divisor /= 10
+            var number = Double(sign) * (Double(integer) + (Double(decimal) / divisor))
+            if hasExponent {
+                if positiveExponent {
+                    for _ in 1...exponent {
+                        number *= Double(10)
+                    }
+                } else {
+                    for _ in 1...exponent {
+                        number /= Double(10)
+                    }
+                }
+            }
+            return JSON.double(number)
+        } else {
+            var number: Int64
+            if isNegative {
+                if integer > UInt64(Int64.max) + 1 {
+                    throw JSONParseError.InvalidNumber(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
+                } else if integer == UInt64(Int64.max) + 1 {
+                    number = Int64.min
+                } else {
+                    number = Int64(integer) * -1
+                }
+            } else {
+                if integer > UInt64(Int64.max) {
+                    throw JSONParseError.InvalidNumber(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
+                } else {
+                    number = Int64(integer)
+                }
+            }
+            return JSON.integer(JSONInteger(number))
+        }
+    }
+
+    func nextBool() throws -> JSON {
+        var expectedWord: [UnicodeScalar]
+        var expectedBool: Bool
+        let lineNumAtStart = lineNumber
+        let charNumAtStart = charNumber
+        if scalar == trueToken[0] {
+            expectedWord = trueToken
+            expectedBool = true
+        } else if scalar == falseToken[0] {
+            expectedWord = falseToken
+            expectedBool = false
+        } else {
+            throw JSONParseError.UnexpectedCharacter(lineNumber: lineNumber, characterNumber: charNumber)
+        }
+        do {
+            let word = try [scalar] + nextScalars(UInt(expectedWord.count - 1))
+            if word != expectedWord {
+                throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
+            }
+        } catch JSONParseError.EndOfFile {
+            throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumAtStart, characterNumber: charNumAtStart)
+        }
+        return JSON.bool(expectedBool)
+    }
+
+    func nextNull() throws -> JSON {
+        let word = try [scalar] + nextScalars(3)
+        if word != nullToken {
+            throw JSONParseError.UnexpectedKeyword(lineNumber: lineNumber, characterNumber: charNumber-4)
+        }
+        return JSON.null
+    }
 }
 
 // MARK:- Unicode Scalars

private let nullToken = [UnicodeScalar]("null".unicodeScalars)

private let escapeMap = [
	"/".unicodeScalars.first!: solidus,
	"b".unicodeScalars.first!: backspace,
	"f".unicodeScalars.first!: formFeed,
	"n".unicodeScalars.first!: lineFeed,
	"r".unicodeScalars.first!: carriageReturn,
	"t".unicodeScalars.first!: tabCharacter
]

private let hexScalars = [
	"0".unicodeScalars.first!,
	"1".unicodeScalars.first!,
	"2".unicodeScalars.first!,
	"3".unicodeScalars.first!,
	"4".unicodeScalars.first!,
	"5".unicodeScalars.first!,
	"6".unicodeScalars.first!,
	"7".unicodeScalars.first!,
	"8".unicodeScalars.first!,
	"9".unicodeScalars.first!,
	"a".unicodeScalars.first!,
	"b".unicodeScalars.first!,
	"c".unicodeScalars.first!,
	"d".unicodeScalars.first!,
	"e".unicodeScalars.first!,
	"f".unicodeScalars.first!
]



/// Errors raised while serializing to a JSON string
public enum JSONSerializeError: ErrorType {
    /// Some unknown error, usually indicates something not yet implemented.
    case Unknown
    /// A number not supported by the JSON spec was encounterd, like infinity or NaN.
    case InvalidNumber
}

/**
    Allows for the Int representation to be switched quickly
    Will maybe be non conformant to the JSON spec on 32bit machines
    Swift 3 will bring #if os(32bit) I think, that will be an approach to fix this.
*/
public typealias JSONInteger = Int

/// Any value that can be expressed in JSON has a representation in `JSON`.
public indirect enum JSON {
    case object([String: JSON])
    case array([JSON])

    case null
    case bool(Bool)
    case string(String)
    case integer(JSONInteger)
    case double(Double)

    /**
        Turns a nested graph of `JSON`s into a Swift `String`. This produces JSON data that
        strictly conforms to [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
        TODO: It can optionally pretty-print the output for debugging, but this comes with a non-negligible performance cost.
    */
    public func jsonString() throws -> String {
        switch self {
        case .array(let a):
            var str = ""
            for (i, v) in a.enumerate() {
                str.appendContentsOf(try v.jsonString())
                guard i != a.endIndex.predecessor() else { break }
                str.appendContentsOf(",")
            }
            return "[" + str + "]"

        case .object(let o):
            var str = ""
            for (i, pair) in o.enumerate() {
                let (key, value) = pair
                let valueJSONString = try value.jsonString()
                let keyPair = ["\"", key, "\":", valueJSONString].joinWithSeparator("")
                str.appendContentsOf(keyPair)
                guard i.successor() != o.count else { break }
                str.appendContentsOf(",")
            }
            return "{" + str + "}"

        case .string(let s):
            var output = ""
            output.append(quotationMark)
            var generator = s.unicodeScalars.generate()
            while let scalar = generator.next() {
                switch scalar.value {
                case solidus.value:
                    fallthrough
                case 0x0000...0x001F:
                    output.append(reverseSolidus)
                    switch scalar {
                    case tabCharacter:
                        output.appendContentsOf("t")
                    case carriageReturn:
                        output.appendContentsOf("r")
                    case lineFeed:
                        output.appendContentsOf("n")
                    case quotationMark:
                        output.append(quotationMark)
                    case backspace:
                        output.appendContentsOf("b")
                    case solidus:
                        output.append(solidus)
                    default:
                        output.appendContentsOf("u")
                        output.append(hexScalars[(Int(scalar.value) & 0xF000) >> 12])
                        output.append(hexScalars[(Int(scalar.value) & 0x0F00) >> 8])
                        output.append(hexScalars[(Int(scalar.value) & 0x00F0) >> 4])
                        output.append(hexScalars[(Int(scalar.value) & 0x000F) >> 0])
                    }
                default:
                    output.append(scalar)
                }
            }
            output.append(quotationMark)
            return output

        case .null: return "null"
        case .bool(let b): return b.description
        case .integer(let i): return i.description
        case .double(let f):
            guard f.isFinite else {
                throw JSONSerializeError.InvalidNumber
            }
            return f.description
        }
    }

    /// Returns this enum's associated Array value if it is one, `nil` otherwise.
    public var array: [JSON]? {
        guard case .array(let a) = self else { return nil }
        return a
    }

    /// Returns this enum's associated Dictionary value if it is one, `nil` otherwise.
    public var object: [String: JSON]? {
        guard case .object(let o) = self else { return nil }
        return o
    }

    /// Returns this enum's associated String value if it is one, `nil` otherwise.
    public var string: String? {
        guard case .string(let s) = self else { return nil }
        return s
    }

    /// Returns this enum's associated `JSONInteger` value if it is one, `nil` otherwise.
    public var int: JSONInteger? {
        guard case .integer(let i) = self else { return nil }
        return i
    }

    /// Returns this enum's associated Bool value if it is one, `nil` otherwise.
    public var bool: Bool? {
        guard case .bool(let b) = self else { return nil }
        return b
    }

    /// Returns this enum's associated Double value if it is one, `nil` otherwise.
    public var double: Double? {
        guard case .double(let d) = self else { return nil }
        return d
    }
}

extension JSON: Equatable {}

public func ==(lhs: JSON, rhs: JSON) -> Bool {
    switch (lhs, rhs) {
    case (.null, .null): return true
    case (.bool(let l), .bool(let r)): return l == r
    case (.array(let l), .array(let r)): return l == r
    case (.string(let l), .string(let r)): return l == r
    case (.object(let l), .object(let r)): return l == r
    case (.integer(let l), .integer(let r)): return l == r
    case (.double(let l), .double(let r)): return l == r

    default: return false
    }
}

extension JSON: IntegerLiteralConvertible {
    public init(integerLiteral value: IntegerLiteralType) {
        let val = JSONInteger(value)
        self = .integer(val)
    }
}

extension JSON: FloatLiteralConvertible {
    public init(floatLiteral value: FloatLiteralType) {
        let val = Double(value)
        self = .double(val)
    }
}

extension JSON : StringLiteralConvertible {
    public init(stringLiteral value: String) {
        self = .string(value)
    }

    public init(extendedGraphemeClusterLiteral value: String) {
        self = .string(value)
    }

    public init(unicodeScalarLiteral value: String) {
        self = .string(value)
    }
}

extension JSON : ArrayLiteralConvertible {
    public init(arrayLiteral elements: JSON...) {
        self = .array(elements)
    }
}

extension JSON : DictionaryLiteralConvertible {
    public init(dictionaryLiteral elements: (String, JSON)...) {
        var dict: [String: JSON] = [:]
        for (k, v) in elements {
            dict[k] = v
        }

        self = .object(dict)
    }
}

extension JSON : NilLiteralConvertible {
    public init(nilLiteral: ()) {
        self = .null
    }
}

extension JSON: BooleanLiteralConvertible {
    public init(booleanLiteral value: Bool) {
        self = .bool(value)
    }
}

extension JSON {
    init(string: String) throws {
        self = .null
    }
}

// MARK:- JSON Accessors

extension JSON {
    /**
        Treat this JSON as a JSON object and attempt to get or set its
        associated Dictionary values.
    */
    public subscript(key: String) -> JSON? {
        get {
            guard case .object(let o) = self else { return nil }
            return o[key]
        }

        set {
            guard case .object(var o) = self else { return }
            o[key] = newValue
            self = .object(o)
        }
    }

    /*
        Treat this JSON as a JSON array and attempt to get or set its
        associated Array values.
        This will do nothing if you attempt to set outside of bounds.
    */
    public subscript(index: Int) -> JSON? {
        get {
            guard case .array(let a) = self where a.indices ~= index else { return nil }
            return a[index]
        }

        set {
            guard case .array(var a) = self where a.indices ~= index else { return }
            switch newValue {
            case .Some(let newValue):
                a[index] = newValue

            case .None:
                a.removeAtIndex(index)
            }
            self = .array(a)
        }
    }
}

/**
    WARNING: Internal type. Used to constrain an extension on Optional
    to be sudo non Generic.
    *DO NOT USE* outside of JSONCore
*/
public protocol _JSONType {}
extension JSON: _JSONType {}

// TODO: Support set through these subscripts
extension Optional where Wrapped: _JSONType {
    /// returns the `JSON` value for key iff `Wrapped` is `JSON.object` and there is a value for the key
    public subscript(key: String) -> JSON? {
        // TODO(ethan): find a better way, should we fatalError() if it isn't `JSON`
        // Would be best if we could constrain extensions to be Non-Generic. Swift3?
        guard let o = (self as? JSON)?.object else { return nil }
        return o[key]
    }

    /// returns the JSON value at index iff `Wrapped` is `JSON.array` and the index is within the arrays bounds
    public subscript(index: Int) -> JSON? {
        guard let a = (self as? JSON)?.array where a.indices ~= index else { return nil }
        return a[index]
    }

    /// Returns an array of `JSON` iff `Wrapped` is `JSON.array`
    public var array: [JSON]? {
        guard let a = (self as? JSON)?.array else { return nil }
        return a
    }

    /// Returns a `JSON` object iff `Wrapped` is `JSON.object`
    public var object: [String: JSON]? {
        guard let o = (self as? JSON)?.object else { return nil }
        return o
    }

    /// Returns a `String` iff `Wrapped` is `JSON.string`
    public var string: String? {
        guard let s = (self as? JSON)?.string else { return nil }
        return s
    }

    /// Returns a `JSONInteger` iff `Wrapped` is `JSON.integer`
    public var int: JSONInteger? {
        guard let i = (self as? JSON)?.int else { return nil }
        return i
    }

    /// Returns a `Bool` iff `Wrapped` is `JSON.bool`
    public var bool: Bool? {
        guard let b = (self as? JSON)?.bool else { return nil }
        return b
    }

    /// Returns a `Double` iff `Wrapped` is `JSON.double`
    public var double: Double? {
        guard let d = (self as? JSON)?.double else { return nil }
        return d
    }
}

// MARK:- Parser
public enum JSONParseError: ErrorType {
    /// Some unknown error, usually indicates something not yet implemented.
    case Unknown
    /// Input data was either empty or contained only whitespace.
    case EmptyInput
    /// Some character that violates the strict JSON grammar was found.
    case UnexpectedCharacter(lineNumber: UInt, characterNumber: UInt)
    /// A JSON string was opened but never closed.
    case UnterminatedString
    /// Any unicode parsing errors will result in this error. Currently unused.
    case InvalidUnicode
    /// A keyword, like `null`, `true`, or `false` was expected but something else was in the input.
    case UnexpectedKeyword(lineNumber: UInt, characterNumber: UInt)
    /// Encountered a JSON number that couldn't be losslessly stored in a `Double` or `Int64`.
    /// Usually the number is too large or too small.
    case InvalidNumber(lineNumber: UInt, characterNumber: UInt)
    /// End of file reached, not always an actual error.
    case EndOfFile
}

// MARK:- Parser
