                     break advancing
                 }
             } catch let InternalError.NumberOverflow(offset: start) {
-                loc = start
-                return try decodeNumberAsString(loc)
+                return try decodeNumberAsString(start)
             }
         }
         

    }
}

private struct NumberIntoStringParser {
    var loc = 0
    var input = UnsafeBufferPointer<UInt8>(start: nil, count: 0)

    mutating func parse(input: UnsafeBufferPointer<UInt8>, inout start: Int) throws {
        assert(!input.isEmpty, "NumberParser should not be given empty input")
        loc = start
        self.input = input

        switch input[loc] {
        case Literal.MINUS:
            try decodeNumberNegative(start)

        case Literal.zero:
            try decodeNumberLeadingZero(start)

        case Literal.one...Literal.nine:
            try decodeNumberPreDecimalDigits(start)

        default:
            preconditionFailure("NumberParser given input that doesn't look like a number")
        }

        start = loc
    }

    mutating func decodeNumberNegative(start: Int) throws {
        loc = loc.successor()

        guard loc < input.count else {
            throw JSONParser.Error.EndOfStreamUnexpected
        }

        switch input[loc] {
        case Literal.zero:
            try decodeNumberLeadingZero(start)

        case Literal.one...Literal.nine:
            try decodeNumberPreDecimalDigits(start)

        default:
            throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
        }
    }

    mutating func decodeNumberLeadingZero(start: Int) throws {
        loc = loc.successor()

        guard loc < input.count && input[loc] == Literal.PERIOD else {
            return
        }

        try decodeNumberDecimal(start)
    }

    mutating func decodeNumberPreDecimalDigits(start: Int) throws {
        loc = loc.successor()

        advancing: while loc < input.count {
            switch input[loc] {
            case Literal.zero...Literal.nine:
                loc = loc.successor()

            case Literal.PERIOD:
                return try decodeNumberDecimal(start)

            case Literal.e, Literal.E:
                return try decodeNumberExponent(start)

            default:
                return
            }
        }
    }

    mutating func decodeNumberDecimal(start: Int) throws {
        loc = loc.successor()

        guard loc < input.count else {
            throw JSONParser.Error.EndOfStreamUnexpected
        }

        switch input[loc] {
        case Literal.zero...Literal.nine:
            try decodeNumberPostDecimalDigits(start)

        default:
            throw JSONParser.Error.NumberMissingFractionalDigits(offset: start)
        }
    }

    mutating func decodeNumberPostDecimalDigits(start: Int) throws {
        loc = loc.successor()

        while loc < input.count && Literal.zero...Literal.nine ~= input[loc] {
            loc = loc.successor()
        }

        if loc < input.count && (input[loc] == Literal.e || input[loc] == Literal.E) {
            return try decodeNumberExponent(start)
        }
    }

    mutating func decodeNumberExponent(start: Int) throws {
        loc = loc.successor()

        guard loc < input.count else {
            throw JSONParser.Error.EndOfStreamUnexpected
        }

        switch input[loc] {
        case Literal.zero...Literal.nine:
            try decodeNumberExponentDigits(start)

        case Literal.PLUS, Literal.MINUS:
            try decodeNumberExponentSign(start)

        default:
            throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
        }
    }

    mutating func decodeNumberExponentSign(start: Int) throws {
        loc = loc.successor()

        guard loc < input.count else {
            throw JSONParser.Error.EndOfStreamUnexpected
        }

        switch input[loc] {
        case Literal.zero...Literal.nine:
            try decodeNumberExponentDigits(start)
            
        default:
            throw JSONParser.Error.NumberSymbolMissingDigits(offset: start)
        }
    }
    
    mutating func decodeNumberExponentDigits(start: Int) throws {
        loc = loc.successor()
        
        while loc < input.count && Literal.zero...Literal.nine ~= input[loc] {
            loc = loc.successor()
        }
    }
}

public extension JSONParser {

    /// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.

        }
    }

    private mutating func decodeNumberAsString(start: Int) throws -> JSON {
        var parser: NumberParser = {
            let state: NumberParser.State
            switch input[start] {
            case Literal.MINUS: state = .LeadingMinus
            case Literal.zero: state = .LeadingZero
            case Literal.one...Literal.nine: state = .PreDecimalDigits
            default:
                fatalError("Internal error: decodeNumber called on not-a-number")
            }
            return NumberParser(loc: start, input: input, state: state)
        }()

        stringDecodingBuffer.removeAll(keepCapacity: true)

        while true {
            switch parser.state {
            case .LeadingMinus:
                try parser.parseNegative()
                stringDecodingBuffer.append(Literal.MINUS)

            case .LeadingZero:
                parser.parseLeadingZero()
                stringDecodingBuffer.append(Literal.zero)

            case .PreDecimalDigits:
                parser.parsePreDecimalDigits { stringDecodingBuffer.append($0) }

            case .Decimal:
                try parser.parseDecimal()
                stringDecodingBuffer.append(Literal.PERIOD)

            case .PostDecimalDigits:
                parser.parsePostDecimalDigits { stringDecodingBuffer.append($0) }

            case .Exponent:
                stringDecodingBuffer.append(input[parser.loc])
                _ = try parser.parseExponent()

            case .ExponentSign:
                stringDecodingBuffer.append(input[parser.loc])
                try parser.parseExponentSign()

            case .ExponentDigits:
                parser.parseExponentDigits { stringDecodingBuffer.append($0) }

            case .Done:
                guard let string = (stringDecodingBuffer.withUnsafeBufferPointer {
                    String.fromCString(UnsafePointer($0.baseAddress))
                    }) else {
                        // Should never fail - any problems with the number string should
                        // result in thrown errors above
                        fatalError("Internal error: Invalid numeric string")
                }

                loc = parser.loc
                return .String(string)
            }
        }
    }

    private func detectingFloatingPointErrors<T>(loc: Int, @noescape _ f: () throws -> T) throws -> T {
