Merge pull request #1204 from ianpartridge/nsnumber-se-0170

diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index 5461afe..424e3e4 100644
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -309,6 +309,7 @@
 		61E011821C1B599A000037DD /* CFMachPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D01BBC9AAC00234F36 /* CFMachPort.c */; };
 		63DCE9D21EAA430100E9CB02 /* ISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */; };
 		63DCE9D41EAA432400E9CB02 /* TestISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */; };
+		684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684C79001F62B611005BD73E /* TestNSNumberBridging.swift */; };
 		6EB768281D18C12C00D4B719 /* UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB768271D18C12C00D4B719 /* UUID.swift */; };
 		7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */; };
 		7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900433A1CACD33E00ECCBF1 /* TestNSPredicate.swift */; };
@@ -767,6 +768,7 @@
 		61F8AE7C1C180FC600FB62F0 /* TestNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNotificationCenter.swift; sourceTree = "<group>"; };
 		63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ISO8601DateFormatter.swift; sourceTree = "<group>"; };
 		63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestISO8601DateFormatter.swift; sourceTree = "<group>"; };
+		684C79001F62B611005BD73E /* TestNSNumberBridging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSNumberBridging.swift; sourceTree = "<group>"; };
 		6E203B8C1C1303BB003B2576 /* TestBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; };
 		6EB768271D18C12C00D4B719 /* UUID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UUID.swift; sourceTree = "<group>"; };
 		790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSCompoundPredicate.swift; sourceTree = "<group>"; };
@@ -1459,6 +1461,7 @@
 				5EF673AB1C28B527006212A3 /* TestNotificationQueue.swift */,
 				5B6F17921C48631C00935030 /* TestNSNull.swift */,
 				EA66F63F1BF1619600136161 /* TestNSNumber.swift */,
+				684C79001F62B611005BD73E /* TestNSNumberBridging.swift */,
 				D5C40F321CDA1D460005690C /* TestOperationQueue.swift */,
 				D834F9931C31C4060023812A /* TestNSOrderedSet.swift */,
 				BDFDF0A61DFF5B3E00C04CC5 /* TestPersonNameComponents.swift */,
@@ -2437,6 +2440,7 @@
 				3EA9D6701EF0532D00B362D6 /* TestJSONEncoder.swift in Sources */,
 				D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */,
 				D4FE895B1D703D1100DA7986 /* TestURLRequest.swift in Sources */,
+				684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */,
 				5B13B33A1C582D4C00651CE2 /* TestNSNumber.swift in Sources */,
 				5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
 				5B13B3311C582D4C00651CE2 /* TestIndexPath.swift in Sources */,
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index 11e5cdc..7dc8cc8 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -32,158 +32,523 @@
 internal let kCFNumberSInt128Type: CFNumberType = 17
 #endif
 
+extension Int8 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int8Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int8Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int8Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int8?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int8?) -> Bool {
+        guard let value = Int8(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int8 {
+        var result: Int8?
+        guard let src = source else { return Int8(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int8(0) }
+        return result!
+    }
+}
+
+extension UInt8 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint8Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint8Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint8Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt8?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt8?) -> Bool {
+        guard let value = UInt8(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt8 {
+        var result: UInt8?
+        guard let src = source else { return UInt8(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt8(0) }
+        return result!
+    }
+}
+
+extension Int16 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int16Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int16Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int16Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int16?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int16?) -> Bool {
+        guard let value = Int16(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int16 {
+        var result: Int16?
+        guard let src = source else { return Int16(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int16(0) }
+        return result!
+    }
+}
+
+extension UInt16 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint16Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint16Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint16Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt16?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt16?) -> Bool {
+        guard let value = UInt16(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt16 {
+        var result: UInt16?
+        guard let src = source else { return UInt16(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt16(0) }
+        return result!
+    }
+}
+
+extension Int32 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int32Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int32Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int32Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int32?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int32?) -> Bool {
+        guard let value = Int32(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int32 {
+        var result: Int32?
+        guard let src = source else { return Int32(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int32(0) }
+        return result!
+    }
+}
+
+extension UInt32 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint32Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint32Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint32Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt32?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt32?) -> Bool {
+        guard let value = UInt32(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt32 {
+        var result: UInt32?
+        guard let src = source else { return UInt32(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt32(0) }
+        return result!
+    }
+}
+
+extension Int64 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int64Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int64Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int64Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int64?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int64?) -> Bool {
+        guard let value = Int64(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int64 {
+        var result: Int64?
+        guard let src = source else { return Int64(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int64(0) }
+        return result!
+    }
+}
+
+extension UInt64 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint64Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint64Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint64Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt64?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt64?) -> Bool {
+        guard let value = UInt64(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt64 {
+        var result: UInt64?
+        guard let src = source else { return UInt64(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt64(0) }
+        return result!
+    }
+}
+
 extension Int : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.intValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.intValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.intValue
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Int?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Int?) -> Bool {
-        result = source.intValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int?) -> Bool {
+        guard let value = Int(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Int {
-        if let object = source {
-            var value: Int?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int {
+        var result: Int?
+        guard let src = source else { return Int(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int(0) }
+        return result!
     }
 }
 
 extension UInt : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.uintValue
     }
 
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+    public init(truncating number: NSNumber) {
+        self = number.uintValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uintValue
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout UInt?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout UInt?) -> Bool {
-        result = source.uintValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt?) -> Bool {
+        guard let value = UInt(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> UInt {
-        if let object = source {
-            var value: UInt?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt {
+        var result: UInt?
+        guard let src = source else { return UInt(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt(0) }
+        return result!
     }
 }
 
 extension Float : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.floatValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.floatValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        guard let value = Double(exactly: number) else { return nil }
+        guard let result = Float(exactly: value) else { return nil }
+        self = result
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Float?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Float?) -> Bool {
-        result = source.floatValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) -> Bool {
+        guard let value = Double(exactly: x) else { return false }
+        guard !value.isNaN else {
+            result = Float.nan
+            return true
+        }
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                result = -Float.infinity
+            } else {
+                result = Float.infinity
+            }
+            return true
+        }
+        guard Swift.abs(value) <= Double(Float.greatestFiniteMagnitude) else {
+            return false
+        }
+
+        result = Float(value)
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Float {
-        if let object = source {
-            var value: Float?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0.0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Float {
+        var result: Float?
+        guard let src = source else { return Float(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Float(0) }
+        return result!
     }
 }
 
 extension Double : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.doubleValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.doubleValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let type = number.objCType.pointee
+        if type == 0x51 {
+            guard let result = Double(exactly: number.uint64Value) else { return nil }
+            self = result
+        } else if type == 0x71 {
+            guard let result = Double(exactly: number.int64Value) else  { return nil }
+            self = result
+        } else {
+            self = number.doubleValue
+        }
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Double?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Double?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Double?) -> Bool {
-        result = source.doubleValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Double?) -> Bool {
+        guard let value = Double(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Double {
-        if let object = source {
-            var value: Double?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0.0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Double {
+        var result: Double?
+        guard let src = source else { return Double(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Double(0) }
+        return result!
     }
 }
 
 extension Bool : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.boolValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.boolValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        if number === kCFBooleanTrue || NSNumber(value: 1) == number {
+            self = true
+        } else if number === kCFBooleanFalse || NSNumber(value: 0) == number {
+            self = false
+        } else {
+            return nil
+        }
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return unsafeBitCast(self ? kCFBooleanTrue : kCFBooleanFalse, to: NSNumber.self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Bool?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Bool?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Bool?) -> Bool {
-        result = source.boolValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Bool?) -> Bool {
+        result = x.boolValue
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Bool {
-        if let object = source {
-            var value: Bool?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return false
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Bool {
+        var result: Bool?
+        guard let src = source else { return false }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return false }
+        return result!
     }
 }
 
diff --git a/Foundation/Stream.swift b/Foundation/Stream.swift
index 84dc566..d34949d 100644
--- a/Foundation/Stream.swift
+++ b/Foundation/Stream.swift
@@ -119,7 +119,7 @@
 
     // reads up to length bytes into the supplied buffer, which must be at least of size len. Returns the actual number of bytes read.
     open func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) -> Int {
-        return CFReadStreamRead(_stream, buffer, CFIndex(len._bridgeToObjectiveC()))
+        return CFReadStreamRead(_stream, buffer, len)
     }
     
     // returns in O(1) a pointer to the buffer in 'buffer' and by reference in 'len' how many bytes are available. This buffer is only valid until the next stream operation. Subclassers may return NO for this if it is not appropriate for the stream type. This may return NO if the buffer is not available.
diff --git a/TestFoundation/TestDecimal.swift b/TestFoundation/TestDecimal.swift
index 3839d53..f626e1e 100644
--- a/TestFoundation/TestDecimal.swift
+++ b/TestFoundation/TestDecimal.swift
@@ -404,7 +404,7 @@
         XCTAssertNotEqual(.noError, NSDecimalMultiplyByPowerOf10(&result, &NaN, 5, .plain))
         XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN e5")
 
-        XCTAssertFalse(Double(NSDecimalNumber(decimal:Decimal(0))).isNaN)
+        XCTAssertFalse(Double(truncating: NSDecimalNumber(decimal: Decimal(0))).isNaN)
     }
 
     func test_NegativeAndZeroMultiplication() {
diff --git a/TestFoundation/TestNSNumberBridging.swift b/TestFoundation/TestNSNumberBridging.swift
new file mode 100644
index 0000000..3edcbaf
--- /dev/null
+++ b/TestFoundation/TestNSNumberBridging.swift
@@ -0,0 +1,866 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+import Foundation
+import XCTest
+#else
+import SwiftFoundation
+import SwiftXCTest
+#endif
+
+class TestNSNumberBridging : XCTestCase {
+    static var allTests: [(String, (TestNSNumberBridging) -> () throws -> Void)] {
+        return [
+            ("testNSNumberBridgeFromInt8", testNSNumberBridgeFromInt8),
+            ("testNSNumberBridgeFromUInt8", testNSNumberBridgeFromUInt8),
+            ("testNSNumberBridgeFromInt16", testNSNumberBridgeFromInt16),
+            ("testNSNumberBridgeFromUInt16", testNSNumberBridgeFromUInt16),
+            ("testNSNumberBridgeFromInt32", testNSNumberBridgeFromInt32),
+            ("testNSNumberBridgeFromUInt32", testNSNumberBridgeFromUInt32),
+            ("testNSNumberBridgeFromInt64", testNSNumberBridgeFromInt64),
+            ("testNSNumberBridgeFromUInt64", testNSNumberBridgeFromUInt64),
+            ("testNSNumberBridgeFromInt", testNSNumberBridgeFromInt),
+            ("testNSNumberBridgeFromUInt", testNSNumberBridgeFromUInt),
+            ("testNSNumberBridgeFromFloat", testNSNumberBridgeFromFloat),
+            ("testNSNumberBridgeFromDouble", testNSNumberBridgeFromDouble),
+            ("test_numericBitPatterns_to_floatingPointTypes", test_numericBitPatterns_to_floatingPointTypes),
+            ("testNSNumberBridgeAnyHashable", testNSNumberBridgeAnyHashable),
+        ]
+    }
+
+    func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
+        let message = "\(file):\(line) \(String(describing: lhs)) != \(String(describing: rhs)) Float"
+        if let lhsValue = lhs {
+            if let rhsValue = rhs {
+                if lhsValue.isNaN != rhsValue.isNaN {
+                    XCTFail(message)
+                } else if lhsValue != rhsValue && !lhsValue.isNaN {
+                    XCTFail(message)
+                }
+            } else {
+                XCTFail(message)
+            }
+        } else {
+            if rhs != nil {
+                XCTFail(message)
+            }
+        }
+    }
+
+    func testDouble(_ lhs: Double?, _ rhs: Double?, file: String = #file, line: UInt = #line) {
+        let message = "\(file):\(line) \(String(describing: lhs)) != \(String(describing: rhs)) Double"
+        if let lhsValue = lhs {
+            if let rhsValue = rhs {
+                if lhsValue.isNaN != rhsValue.isNaN {
+                    XCTFail(message)
+                } else if lhsValue != rhsValue && !lhsValue.isNaN {
+                    XCTFail(message)
+                }
+            } else {
+                XCTFail(message)
+            }
+        } else {
+            if rhs != nil {
+                XCTFail(message)
+            }
+        }
+    }
+
+    func testNSNumberBridgeFromInt8() {
+        for interestingValue in Int8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt8() {
+        for interestingValue in UInt8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt16() {
+        for interestingValue in Int16._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt16() {
+        for interestingValue in UInt8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt32() {
+        for interestingValue in Int32._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                let expectedFloat = Float(exactly: int32!)
+                // these are disabled because of https://bugs.swift.org/browse/SR-4634
+                if (int32! != Int32.min && int32! != Int32.max &&
+                    int32! != Int32.min + 1 && int32! != Int32.max - 1) {
+                    testFloat(expectedFloat, float)
+                }
+                let double = Double(exactly: number!)
+                let expectedDouble = Double(exactly: int32!)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt32() {
+        for interestingValue in UInt32._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                let expectedFloat = Float(exactly: uint32!)
+                // these are disabled because of https://bugs.swift.org/browse/SR-4634
+                if (uint32! != UInt32.max && uint32! != UInt32.max - 1) {
+                    testFloat(expectedFloat, float)
+                }
+                let double = Double(exactly: number!)
+                let expectedDouble = Double(exactly: uint32!)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt64() {
+        for interestingValue in Int64._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt64() {
+        for interestingValue in UInt64._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt() {
+        for interestingValue in Int._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt() {
+        for interestingValue in UInt._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromFloat() {
+        for interestingValue in Float._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+
+                let float = Float(truncating: number!)
+                let expectedFloat = interestingValue
+                testFloat(expectedFloat, float)
+
+                let double = Double(truncating: number!)
+                let expectedDouble = Double(reasonably: interestingValue)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromDouble() {
+        for interestingValue in Double._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+
+                let float = Float(truncating: number!)
+                let expectedFloat = Float(reasonably: interestingValue)
+                testFloat(expectedFloat, float)
+
+                let double = Double(exactly: number!)
+                let expectedDouble = interestingValue
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func test_numericBitPatterns_to_floatingPointTypes() {
+        let signed_numbers: [NSNumber] = [
+            NSNumber(value: Int64(6)),
+            NSNumber(value: Int64(bitPattern: 1 << 56)),
+            NSNumber(value: Int64(bitPattern: 1 << 53)),
+            NSNumber(value: Int64(bitPattern: 1 << 52)),
+            NSNumber(value: Int64(bitPattern: 1 << 25)),
+            NSNumber(value: Int64(bitPattern: 1 << 24)),
+            NSNumber(value: Int64(bitPattern: 1 << 23)),
+            NSNumber(value: -Int64(bitPattern: 1 << 53)),
+            NSNumber(value: -Int64(bitPattern: 1 << 52)),
+            NSNumber(value: -Int64(6)),
+            NSNumber(value: -Int64(bitPattern: 1 << 56)),
+            NSNumber(value: -Int64(bitPattern: 1 << 25)),
+            NSNumber(value: -Int64(bitPattern: 1 << 24)),
+            NSNumber(value: -Int64(bitPattern: 1 << 23)),
+            ]
+
+        let signed_values: [Int64] = [
+            Int64(6),
+            Int64(bitPattern: 1 << 56),
+            Int64(bitPattern: 1 << 53),
+            Int64(bitPattern: 1 << 52),
+            Int64(bitPattern: 1 << 25),
+            Int64(bitPattern: 1 << 24),
+            Int64(bitPattern: 1 << 23),
+            -Int64(bitPattern: 1 << 53),
+            -Int64(bitPattern: 1 << 52),
+            -Int64(6),
+            -Int64(bitPattern: 1 << 56),
+            -Int64(bitPattern: 1 << 25),
+            -Int64(bitPattern: 1 << 24),
+            -Int64(bitPattern: 1 << 23),
+            ]
+
+        let unsigned_numbers: [NSNumber] = [
+            NSNumber(value: UInt64(bitPattern: 6)),
+            NSNumber(value: UInt64(bitPattern: 1 << 56)),
+            NSNumber(value: UInt64(bitPattern: 1 << 63)),
+            NSNumber(value: UInt64(bitPattern: 1 << 53)),
+            NSNumber(value: UInt64(bitPattern: 1 << 52)),
+            NSNumber(value: UInt64(bitPattern: 1 << 25)),
+            NSNumber(value: UInt64(bitPattern: 1 << 24)),
+            NSNumber(value: UInt64(bitPattern: 1 << 23)),
+            ]
+
+        let unsigned_values: [UInt64] = [
+            UInt64(bitPattern: 6),
+            UInt64(bitPattern: 1 << 56),
+            UInt64(bitPattern: 1 << 63),
+            UInt64(bitPattern: 1 << 53),
+            UInt64(bitPattern: 1 << 52),
+            UInt64(bitPattern: 1 << 25),
+            UInt64(bitPattern: 1 << 24),
+            UInt64(bitPattern: 1 << 23)
+        ]
+
+        for (number, value) in zip(signed_numbers, signed_values) {
+            let numberCast = Double(exactly: number)
+            let valueCast = Double(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(unsigned_numbers, unsigned_values) {
+            let numberCast = Double(exactly: number)
+            let valueCast = Double(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(signed_numbers, signed_values) {
+            let numberCast = Float(exactly: number)
+            let valueCast = Float(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(unsigned_numbers, unsigned_values) {
+            let numberCast = Float(exactly: number)
+            let valueCast = Float(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+    }
+
+    func testNSNumberBridgeAnyHashable() {
+        var dict = [AnyHashable : Any]()
+        for i in -Int(UInt8.min) ... Int(UInt8.max) {
+            dict[i] = "\(i)"
+        }
+
+        // When bridging a dictionary to NSDictionary, we should be able to access
+        // the keys through either an Int (the original type boxed in AnyHashable)
+        // or NSNumber (the type Int bridged to).
+        let ns_dict = dict._bridgeToObjectiveC()
+        for i in -Int(UInt8.min) ... Int(UInt8.max) {
+            guard let value = ns_dict[i] as? String else {
+                XCTFail("Unable to look up value by Int key.")
+                continue
+            }
+
+            guard let ns_value = ns_dict[NSNumber(value: i)] as? String else {
+                XCTFail("Unable to look up value by NSNumber key.")
+                continue
+            }
+
+            XCTAssertEqual(value, ns_value)
+        }
+    }
+}
+
+extension Float {
+    init?(reasonably value: Float) {
+        self = value
+    }
+
+    init?(reasonably value: Double) {
+        guard !value.isNaN else {
+            self = Float.nan
+            return
+        }
+
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                self = -Float.infinity
+            } else {
+                self = Float.infinity
+            }
+            return
+        }
+
+        guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
+            return nil
+        }
+
+        self = Float(value)
+    }
+}
+
+extension Double {
+    init?(reasonably value: Float) {
+        guard !value.isNaN else {
+            self = Double.nan
+            return
+        }
+
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                self = -Double.infinity
+            } else {
+                self = Double.infinity
+            }
+            return
+        }
+
+        self = Double(value)
+    }
+
+    init?(reasonably value: Double) {
+        self = value
+    }
+}
+
+extension Int8 {
+    static var _interestingValues: [Int8] {
+        return [
+            Int8.min,
+            Int8.min + 1,
+            Int8.max,
+            Int8.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt8 {
+    static var _interestingValues: [UInt8] {
+        return [
+            UInt8.min,
+            UInt8.min + 1,
+            UInt8.max,
+            UInt8.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int16 {
+    static var _interestingValues: [Int16] {
+        return [
+            Int16.min,
+            Int16.min + 1,
+            Int16.max,
+            Int16.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt16 {
+    static var _interestingValues: [UInt16] {
+        return [
+            UInt16.min,
+            UInt16.min + 1,
+            UInt16.max,
+            UInt16.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int32 {
+    static var _interestingValues: [Int32] {
+        return [
+            Int32.min,
+            Int32.min + 1,
+            Int32.max,
+            Int32.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt32 {
+    static var _interestingValues: [UInt32] {
+        return [
+            UInt32.min,
+            UInt32.min + 1,
+            UInt32.max,
+            UInt32.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int64 {
+    static var _interestingValues: [Int64] {
+        return [
+            Int64.min,
+            Int64.min + 1,
+            Int64.max,
+            Int64.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt64 {
+    static var _interestingValues: [UInt64] {
+        return [
+            UInt64.min,
+            UInt64.min + 1,
+            UInt64.max,
+            UInt64.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int {
+    static var _interestingValues: [Int] {
+        return [
+            Int.min,
+            Int.min + 1,
+            Int.max,
+            Int.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt {
+    static var _interestingValues: [UInt] {
+        return [
+            UInt.min,
+            UInt.min + 1,
+            UInt.max,
+            UInt.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Float {
+    static var _interestingValues: [Float] {
+        return [
+            -Float.infinity,
+            -Float.greatestFiniteMagnitude,
+            -1.0,
+            -Float.ulpOfOne,
+            -Float.leastNormalMagnitude,
+            -0.0,
+            0.0,
+            Float.leastNormalMagnitude,
+            Float.ulpOfOne,
+            1.0,
+            Float.greatestFiniteMagnitude,
+            Float.infinity,
+            Float.nan,
+        ]
+    }
+}
+
+extension Double {
+    static var _interestingValues: [Double] {
+        return [
+            -Double.infinity,
+            //-Double.greatestFiniteMagnitude,
+            -1.0,
+            -Double.ulpOfOne,
+            -Double.leastNormalMagnitude,
+            -0.0,
+            0.0,
+            Double.leastNormalMagnitude,
+            Double.ulpOfOne,
+            1.0,
+            //Double.greatestFiniteMagnitude,
+            Double.infinity,
+            Double.nan,
+        ]
+    }
+}
diff --git a/TestFoundation/main.swift b/TestFoundation/main.swift
index 9ae6d0f..cefca93 100644
--- a/TestFoundation/main.swift
+++ b/TestFoundation/main.swift
@@ -58,6 +58,7 @@
     testCase(TestNotificationQueue.allTests),
     testCase(TestNSNull.allTests),
     testCase(TestNSNumber.allTests),
+    testCase(TestNSNumberBridging.allTests),
     testCase(TestNumberFormatter.allTests),
     testCase(TestOperationQueue.allTests),
     testCase(TestNSOrderedSet.allTests),