Merge pull request #684 from e78l/numfmt

NSNumberFormatter implementation progress
diff --git a/Docs/Status.md b/Docs/Status.md
index de77b21..6c0eb68 100644
--- a/Docs/Status.md
+++ b/Docs/Status.md
@@ -47,7 +47,7 @@
     |------------------------------|-----------------|---------------|--------------------------------------------------------------------------------------------------------------------|
     | `URLAuthenticationChallenge` | Unimplemented   | None          |                                                                                                                    |
     | `URLCache`                   | Unimplemented   | None          |                                                                                                                    |
-    | `URLCredential`              | Mostly Complete | Incomplete    | `NSCoding` and `NSCopying` remain unimplemented                                                                    |
+    | `URLCredential`              | Mostly Complete | Incomplete    | `NSCopying` remains unimplemented                                                                                  |
     | `URLCredentialStorage`       | Unimplemented   | None          |                                                                                                                    |
     | `NSURLError*`                | Complete        | N/A           |                                                                                                                    |
     | `URLProtectionSpace`         | Unimplemented   | None          |                                                                                                                    |
diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index a16ff38..2af4035 100755
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		0383A1751D2E558A0052E5D1 /* TestNSStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0383A1741D2E558A0052E5D1 /* TestNSStream.swift */; };
 		1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; };
+		231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */; };
 		294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
 		2EBE67A51C77BF0E006583D5 /* TestNSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */; };
 		528776141BF2629700CB0090 /* FoundationErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522C253A1BF16E1600804FC6 /* FoundationErrors.swift */; };
@@ -307,6 +308,7 @@
 		7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */; };
 		7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900433A1CACD33E00ECCBF1 /* TestNSPredicate.swift */; };
 		AE35A1861CBAC85E0042DB84 /* SwiftFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = AE35A1851CBAC85E0042DB84 /* SwiftFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		BF8E65311DC3B3CB005AB5C3 /* TestNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8E65301DC3B3CB005AB5C3 /* TestNotification.swift */; };
 		CC5249C01D341D23007CB54D /* TestUnitConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC5249BF1D341D23007CB54D /* TestUnitConverter.swift */; };
 		CE19A88C1C23AA2300B4CB6A /* NSStringTestData.txt in Resources */ = {isa = PBXBuildFile; fileRef = CE19A88B1C23AA2300B4CB6A /* NSStringTestData.txt */; };
 		D31302011C30CEA900295652 /* NSConcreteValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D31302001C30CEA900295652 /* NSConcreteValue.swift */; };
@@ -336,6 +338,7 @@
 		EA08126B1DA80C3600651B70 /* TestNSProgressFraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA08126A1DA80C3600651B70 /* TestNSProgressFraction.swift */; };
 		EA08126C1DA810BE00651B70 /* ProgressFraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0812681DA71C8A00651B70 /* ProgressFraction.swift */; };
 		EA418C261D57257D005EAD0D /* NSKeyedArchiverHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA418C251D57257D005EAD0D /* NSKeyedArchiverHelpers.swift */; };
+		EA54A6FB1DB16D53009E0809 /* TestObjCRuntime.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA54A6FA1DB16D53009E0809 /* TestObjCRuntime.swift */; };
 		EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */ = {isa = PBXBuildFile; fileRef = EA66F6351BEED03E00136161 /* TargetConditionals.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		EA66F6481BF1619600136161 /* NSURLTestData.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA66F63B1BF1619600136161 /* NSURLTestData.plist */; };
 		EA66F6671BF2F2F100136161 /* CoreFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = EA66F6651BF2F2E800136161 /* CoreFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -455,6 +458,7 @@
 		0383A1741D2E558A0052E5D1 /* TestNSStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSStream.swift; sourceTree = "<group>"; };
 		1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = "<group>"; };
 		22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDate.swift; sourceTree = "<group>"; };
+		231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDecimal.swift; sourceTree = "<group>"; };
 		294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
 		2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDateFormatter.swift; sourceTree = "<group>"; };
 		400E22641C1A4E58007C5933 /* TestNSProcessInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSProcessInfo.swift; sourceTree = "<group>"; };
@@ -741,6 +745,7 @@
 		88D28DE61C13AE9000494606 /* TestNSGeometry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSGeometry.swift; sourceTree = "<group>"; };
 		A5A34B551C18C85D00FD972B /* TestNSByteCountFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSByteCountFormatter.swift; sourceTree = "<group>"; };
 		AE35A1851CBAC85E0042DB84 /* SwiftFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftFoundation.h; sourceTree = "<group>"; };
+		BF8E65301DC3B3CB005AB5C3 /* TestNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNotification.swift; sourceTree = "<group>"; };
 		C2A9D75B1C15C08B00993803 /* TestNSUUID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSUUID.swift; sourceTree = "<group>"; };
 		C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAffineTransform.swift; sourceTree = "<group>"; };
 		CC5249BF1D341D23007CB54D /* TestUnitConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUnitConverter.swift; sourceTree = "<group>"; };
@@ -780,6 +785,7 @@
 		EA313DFE1BE7F2E90060A403 /* CFURLComponents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLComponents.c; sourceTree = "<group>"; };
 		EA313DFF1BE7F2E90060A403 /* CFURLComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFURLComponents.h; sourceTree = "<group>"; };
 		EA418C251D57257D005EAD0D /* NSKeyedArchiverHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSKeyedArchiverHelpers.swift; sourceTree = "<group>"; };
+		EA54A6FA1DB16D53009E0809 /* TestObjCRuntime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestObjCRuntime.swift; sourceTree = "<group>"; };
 		EA66F6351BEED03E00136161 /* TargetConditionals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetConditionals.h; path = CoreFoundation/Base.subproj/SwiftRuntime/TargetConditionals.h; sourceTree = SOURCE_ROOT; };
 		EA66F6381BF1619600136161 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
 		EA66F63B1BF1619600136161 /* NSURLTestData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = NSURLTestData.plist; sourceTree = "<group>"; };
@@ -1324,6 +1330,7 @@
 				DCDBB8321C1768AC00313299 /* TestNSData.swift */,
 				22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */,
 				2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */,
+				231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */,
 				EA66F63D1BF1619600136161 /* TestNSDictionary.swift */,
 				D512D17B1CD883F00032E6A5 /* TestNSFileHandle.swift */,
 				525AECEB1BF2C96400D15BB0 /* TestNSFileManager.swift */,
@@ -1372,6 +1379,8 @@
 				5B6F17961C48631C00935030 /* TestUtils.swift */,
 				0383A1741D2E558A0052E5D1 /* TestNSStream.swift */,
 				5B1FD9E21D6D17B80080E83C /* TestNSURLSession.swift */,
+				EA54A6FA1DB16D53009E0809 /* TestObjCRuntime.swift */,
+				BF8E65301DC3B3CB005AB5C3 /* TestNotification.swift */,
 			);
 			name = Tests;
 			sourceTree = "<group>";
@@ -2205,9 +2214,11 @@
 				5B13B3331C582D4C00651CE2 /* TestNSJSONSerialization.swift in Sources */,
 				5B13B33C1C582D4C00651CE2 /* TestNSOrderedSet.swift in Sources */,
 				5B13B34A1C582D4C00651CE2 /* TestNSURL.swift in Sources */,
+				EA54A6FB1DB16D53009E0809 /* TestObjCRuntime.swift in Sources */,
 				5B13B34D1C582D4C00651CE2 /* TestNSUUID.swift in Sources */,
 				5B13B3281C582D4C00651CE2 /* TestNSBundle.swift in Sources */,
 				5B13B32A1C582D4C00651CE2 /* TestNSCharacterSet.swift in Sources */,
+				BF8E65311DC3B3CB005AB5C3 /* TestNotification.swift in Sources */,
 				EA01AAEC1DA839C4008F4E07 /* TestProgress.swift in Sources */,
 				5B13B3411C582D4C00651CE2 /* TestNSRegularExpression.swift in Sources */,
 				5B13B3491C582D4C00651CE2 /* TestNSTimeZone.swift in Sources */,
@@ -2216,6 +2227,7 @@
 				5B13B33E1C582D4C00651CE2 /* TestNSProcessInfo.swift in Sources */,
 				5B13B33F1C582D4C00651CE2 /* TestNSPropertyList.swift in Sources */,
 				5B13B32C1C582D4C00651CE2 /* TestNSDate.swift in Sources */,
+				231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */,
 				7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */,
 				5B13B33B1C582D4C00651CE2 /* TestNSNumberFormatter.swift in Sources */,
 				5B13B3301C582D4C00651CE2 /* TestNSHTTPCookie.swift in Sources */,
diff --git a/Foundation/CGFloat.swift b/Foundation/CGFloat.swift
index bba73b4..3462d8d 100644
--- a/Foundation/CGFloat.swift
+++ b/Foundation/CGFloat.swift
@@ -145,15 +145,17 @@
     public var native: NativeType
 }
 
-@_transparent extension CGFloat : BinaryFloatingPoint {
+extension CGFloat : BinaryFloatingPoint {
     
     public typealias RawSignificand = UInt
     public typealias Exponent = Int
-    
+
+    @_transparent
     public static var exponentBitCount: Int {
         return NativeType.exponentBitCount
     }
     
+    @_transparent
     public static var significandBitCount: Int {
         return NativeType.significandBitCount
     }
@@ -161,10 +163,12 @@
     //  Conversions to/from integer encoding.  These are not part of the
     //  BinaryFloatingPoint prototype because there's no guarantee that an
     //  integer type of the same size actually exists (e.g. Float80).
+    @_transparent
     public var bitPattern: UInt {
         return UInt(native.bitPattern)
     }
-    
+
+    @_transparent
     public init(bitPattern: UInt) {
 #if arch(i386) || arch(arm)
         native = NativeType(bitPattern: UInt32(bitPattern))
@@ -172,19 +176,23 @@
         native = NativeType(bitPattern: UInt64(bitPattern))
 #endif
     }
-    
+
+    @_transparent
     public var sign: FloatingPointSign {
         return native.sign
     }
-    
+
+    @_transparent
     public var exponentBitPattern: UInt {
         return native.exponentBitPattern
     }
-    
+
+    @_transparent
     public var significandBitPattern: UInt {
         return UInt(native.significandBitPattern)
     }
-    
+
+    @_transparent
     public init(sign: FloatingPointSign,
                 exponentBitPattern: UInt,
                 significandBitPattern: UInt) {
@@ -192,177 +200,217 @@
                             exponentBitPattern: exponentBitPattern,
                             significandBitPattern: NativeType.RawSignificand(significandBitPattern))
     }
-    
+
+    @_transparent
     public init(nan payload: RawSignificand, signaling: Bool) {
         native = NativeType(nan: NativeType.RawSignificand(payload),
                             signaling: signaling)
     }
-    
+
+    @_transparent
     public static var infinity: CGFloat {
         return CGFloat(NativeType.infinity)
     }
-    
+
+    @_transparent
     public static var nan: CGFloat {
         return CGFloat(NativeType.nan)
     }
-    
+
+    @_transparent
     public static var signalingNaN: CGFloat {
         return CGFloat(NativeType.signalingNaN)
     }
-    
+
     @available(*, unavailable, renamed: "nan")
     public static var quietNaN: CGFloat {
         fatalError("unavailable")
     }
-    
+
+    @_transparent
     public static var greatestFiniteMagnitude: CGFloat {
         return CGFloat(NativeType.greatestFiniteMagnitude)
     }
-    
+
+    @_transparent
     public static var pi: CGFloat {
         return CGFloat(NativeType.pi)
     }
-    
+
+    @_transparent
     public var ulp: CGFloat {
         return CGFloat(native.ulp)
     }
-    
+
+    @_transparent
     public static var leastNormalMagnitude: CGFloat {
         return CGFloat(NativeType.leastNormalMagnitude)
     }
-    
+
+    @_transparent
     public static var leastNonzeroMagnitude: CGFloat {
         return CGFloat(NativeType.leastNonzeroMagnitude)
     }
-    
+
+    @_transparent
     public var exponent: Int {
         return native.exponent
     }
-    
+
+    @_transparent
     public var significand: CGFloat {
         return CGFloat(native.significand)
     }
-    
+
+    @_transparent
     public init(sign: FloatingPointSign, exponent: Int, significand: CGFloat) {
         native = NativeType(sign: sign,
                             exponent: exponent, significand: significand.native)
     }
-    
+
+    @_transparent
     public mutating func round(_ rule: FloatingPointRoundingRule) {
         native.round(rule)
     }
-    
+
+    @_transparent
     public var nextUp: CGFloat {
         return CGFloat(native.nextUp)
     }
-    
+
+    @_transparent
     public var magnitude: CGFloat {
         return CGFloat(Swift.abs(native))
     }
-    
+
+    @_transparent
     public mutating func negate() {
         native.negate()
     }
-    
+
+    @_transparent
     public mutating func add(_ other: CGFloat) {
         native.add(other.native)
     }
-    
+
+    @_transparent
     public mutating func subtract(_ other: CGFloat) {
         native.subtract(other.native)
     }
-    
+
+    @_transparent
     public mutating func multiply(by other: CGFloat) {
         native.multiply(by: other.native)
     }
-    
+
+    @_transparent
     public mutating func divide(by other: CGFloat) {
         native.divide(by: other.native)
     }
-    
+
+    @_transparent
     public mutating func formTruncatingRemainder(dividingBy other: CGFloat) {
         native.formTruncatingRemainder(dividingBy: other.native)
     }
-    
+
+    @_transparent
     public mutating func formRemainder(dividingBy other: CGFloat) {
         native.formRemainder(dividingBy: other.native)
     }
-    
+
+    @_transparent
     public mutating func formSquareRoot( ) {
         native.formSquareRoot( )
     }
-    
+
+    @_transparent
     public mutating func addProduct(_ lhs: CGFloat, _ rhs: CGFloat) {
         native.addProduct(lhs.native, rhs.native)
     }
-    
+
+    @_transparent
     public func isEqual(to other: CGFloat) -> Bool {
         return self.native.isEqual(to: other.native)
     }
-    
+
+    @_transparent
     public func isLess(than other: CGFloat) -> Bool {
         return self.native.isLess(than: other.native)
     }
-    
+
+    @_transparent
     public func isLessThanOrEqualTo(_ other: CGFloat) -> Bool {
         return self.native.isLessThanOrEqualTo(other.native)
     }
-    
+
+    @_transparent
     public var isNormal:  Bool {
         return native.isNormal
     }
-    
+
+    @_transparent
     public var isFinite:  Bool {
         return native.isFinite
     }
-    
+
+    @_transparent
     public var isZero:  Bool {
         return native.isZero
     }
-    
+
+    @_transparent
     public var isSubnormal:  Bool {
         return native.isSubnormal
     }
-    
+
+    @_transparent
     public var isInfinite:  Bool {
         return native.isInfinite
     }
-    
+
+    @_transparent
     public var isNaN:  Bool {
         return native.isNaN
     }
-    
+
+    @_transparent
     public var isSignalingNaN: Bool {
         return native.isSignalingNaN
     }
-    
+
     @available(*, unavailable, renamed: "isSignalingNaN")
     public var isSignaling: Bool {
         fatalError("unavailable")
     }
-    
+
+    @_transparent
     public var isCanonical: Bool {
         return true
     }
-    
+
+    @_transparent
     public var floatingPointClass: FloatingPointClassification {
         return native.floatingPointClass
     }
-    
+
+    @_transparent
     public var binade: CGFloat {
         return CGFloat(native.binade)
     }
-    
+
+    @_transparent
     public var significandWidth: Int {
         return native.significandWidth
     }
-    
+
     /// Create an instance initialized to `value`.
+    @_transparent
     public init(floatLiteral value: NativeType) {
         native = value
     }
-    
+
     /// Create an instance initialized to `value`.
+    @_transparent
     public init(integerLiteral value: Int) {
         native = NativeType(value)
     }
@@ -402,14 +450,14 @@
     }
 }
 
-@_transparent extension CGFloat : CustomStringConvertible {
+extension CGFloat : CustomStringConvertible {
     /// A textual representation of `self`.
     public var description: String {
         return native.description
     }
 }
 
-@_transparent extension CGFloat : Hashable {
+extension CGFloat : Hashable {
     /// The hash value.
     ///
     /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
@@ -417,78 +465,91 @@
     /// - Note: the hash value is not guaranteed to be stable across
     ///   different invocations of the same program.  Do not persist the
     ///   hash value across program runs.
+    @_transparent
     public var hashValue: Int {
         return native.hashValue
     }
 }
 
-@_transparent extension UInt8 {
+extension UInt8 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = UInt8(value.native)
     }
 }
 
-@_transparent extension Int8 {
+extension Int8 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Int8(value.native)
     }
 }
 
-@_transparent extension UInt16 {
+extension UInt16 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = UInt16(value.native)
     }
 }
 
-@_transparent extension Int16 {
+extension Int16 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Int16(value.native)
     }
 }
 
-@_transparent extension UInt32 {
+extension UInt32 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = UInt32(value.native)
     }
 }
 
-@_transparent extension Int32 {
+extension Int32 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Int32(value.native)
     }
 }
 
-@_transparent extension UInt64 {
+extension UInt64 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = UInt64(value.native)
     }
 }
 
-@_transparent extension Int64 {
+extension Int64 {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Int64(value.native)
     }
 }
 
-@_transparent extension UInt {
+extension UInt {
+    @_transparent
     public init(_ value: CGFloat) {
         self = UInt(value.native)
     }
 }
 
-@_transparent extension Int {
+extension Int {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Int(value.native)
     }
 }
 
-@_transparent extension Double {
+extension Double {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Double(value.native)
     }
 }
 
-@_transparent extension Float {
+extension Float {
+    @_transparent
     public init(_ value: CGFloat) {
         self = Float(value.native)
     }
@@ -547,7 +608,7 @@
 // Strideable Conformance
 //===----------------------------------------------------------------------===//
 
-@_transparent extension CGFloat : Strideable {
+extension CGFloat : Strideable {
     /// Returns a stride `x` such that `self.advanced(by: x)` approximates
     /// `other`.
     ///
@@ -571,41 +632,35 @@
 // Deprecated operators
 //===----------------------------------------------------------------------===//
 
-@_transparent
 @available(*, unavailable, message: "use += 1")
 @discardableResult
 public prefix func ++(rhs: inout CGFloat) -> CGFloat {
     fatalError("++ is not available")
 }
 
-@_transparent
 @available(*, unavailable, message: "use -= 1")
 @discardableResult
 public prefix func --(rhs: inout CGFloat) -> CGFloat {
     fatalError("-- is not available")
 }
 
-@_transparent
 @available(*, unavailable, message: "use += 1")
 @discardableResult
 public postfix func ++(lhs: inout CGFloat) -> CGFloat {
     fatalError("++ is not available")
 }
 
-@_transparent
 @available(*, unavailable, message: "use -= 1")
 @discardableResult
 public postfix func --(lhs: inout CGFloat) -> CGFloat {
     fatalError("-- is not available")
 }
 
-@_transparent
 @available(*, unavailable, message: "Use truncatingRemainder instead")
 public func %(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
     fatalError("% is not available.")
 }
 
-@_transparent
 @available(*, unavailable, message: "Use formTruncatingRemainder instead")
 public func %=(lhs: inout CGFloat, rhs: CGFloat) {
     fatalError("%= is not available.")
@@ -880,16 +935,17 @@
     return CGFloat(yn(n, Double(x.native)))
 }
 
-@_transparent
 extension CGFloat : _CVarArgPassedAsDouble, _CVarArgAligned {
     /// Transform `self` into a series of machine words that can be
     /// appropriately interpreted by C varargs
+    @_transparent
     public var _cVarArgEncoding: [Int] {
         return native._cVarArgEncoding
     }
     
     /// Return the required alignment in bytes of 
     /// the value returned by `_cVarArgEncoding`.
+    @_transparent
     public var _cVarArgAlignment: Int { 
         return native._cVarArgAlignment
     }
diff --git a/Foundation/CharacterSet.swift b/Foundation/CharacterSet.swift
index 4babf01..35fbe72 100644
--- a/Foundation/CharacterSet.swift
+++ b/Foundation/CharacterSet.swift
@@ -13,6 +13,10 @@
 private func _utfRangeToNSRange(_ inRange : Range<UnicodeScalar>) -> NSRange {
     return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value))
 }
+ 
+private func _utfRangeToNSRange(_ inRange : ClosedRange<UnicodeScalar>) -> NSRange {
+    return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value + 1))
+}
 
 internal final class _SwiftNSCharacterSet : NSCharacterSet, _SwiftNativeFoundationType {
     internal typealias ImmutableType = NSCharacterSet
@@ -129,8 +133,7 @@
     ///
     /// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
     public init(charactersIn range: ClosedRange<UnicodeScalar>) {
-        let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
-        _wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(halfOpenRange)))
+        _wrapped = _SwiftNSCharacterSet(immutableObject: NSCharacterSet(range: _utfRangeToNSRange(range)))
     }
     
     /// Initialize with the characters in the given string.
@@ -320,8 +323,7 @@
     ///
     /// It is the caller's responsibility to ensure that the values represent valid `UnicodeScalar` values, if that is what is desired.
     public mutating func insert(charactersIn range: ClosedRange<UnicodeScalar>) {
-        let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
-        let nsRange = _utfRangeToNSRange(halfOpenRange)
+        let nsRange = _utfRangeToNSRange(range)
         _applyUnmanagedMutation {
             $0.addCharacters(in: nsRange)
         }
@@ -337,8 +339,7 @@
     
     /// Remove a closed range of integer values from the `CharacterSet`.
     public mutating func remove(charactersIn range: ClosedRange<UnicodeScalar>) {
-        let halfOpenRange = range.lowerBound..<UnicodeScalar(range.upperBound.value + 1)!
-        let nsRange = _utfRangeToNSRange(halfOpenRange)
+        let nsRange = _utfRangeToNSRange(range)
         _applyUnmanagedMutation {
             $0.removeCharacters(in: nsRange)
         }
diff --git a/Foundation/Locale.swift b/Foundation/Locale.swift
index ffe584a..46642ac 100644
--- a/Foundation/Locale.swift
+++ b/Foundation/Locale.swift
@@ -69,7 +69,7 @@
     
     /// Returns a localized string for a specified identifier.
     ///
-    /// For example, in the "en" locale, the result for `"en"` is `"Spanish"`.
+    /// For example, in the "en" locale, the result for `"es"` is `"Spanish"`.
     public func localizedString(forIdentifier identifier: String) -> String? {
         return _wrapped.displayName(forKey: .identifier, value: identifier)
     }
@@ -83,7 +83,7 @@
     
     /// Returns a localized string for a specified region code.
     ///
-    /// For example, in the "en" locale, the result for `"fr"` is `"French"`.
+    /// For example, in the "en" locale, the result for `"fr"` is `"France"`.
     public func localizedString(forRegionCode regionCode: String) -> String? {
         return _wrapped.displayName(forKey: .countryCode, value: regionCode)
     }
diff --git a/Foundation/NSCFString.swift b/Foundation/NSCFString.swift
index e12e0fa..4558549 100644
--- a/Foundation/NSCFString.swift
+++ b/Foundation/NSCFString.swift
@@ -140,19 +140,18 @@
 }
 
 internal func _CFSwiftStringGetBytes(_ str: AnyObject, encoding: CFStringEncoding, range: CFRange, buffer: UnsafeMutablePointer<UInt8>?, maxBufLen: CFIndex, usedBufLen: UnsafeMutablePointer<CFIndex>?) -> CFIndex {
+    let convertedLength: CFIndex
     switch encoding {
         // TODO: Don't treat many encodings like they are UTF8
     case CFStringEncoding(kCFStringEncodingUTF8), CFStringEncoding(kCFStringEncodingISOLatin1), CFStringEncoding(kCFStringEncodingMacRoman), CFStringEncoding(kCFStringEncodingASCII), CFStringEncoding(kCFStringEncodingNonLossyASCII):
-        let encodingView = (str as! NSString)._swiftObject.utf8
-        let start = encodingView.startIndex
+        let encodingView = (str as! NSString).substring(with: NSRange(range)).utf8
         if let buffer = buffer {
-            for idx in 0..<range.length {
-                let characterIndex = encodingView.index(start, offsetBy: idx + range.location)
-                let character = encodingView[characterIndex]
+            for (idx, character) in encodingView.enumerated() {
                 buffer.advanced(by: idx).initialize(to: character)
             }
         }
-        usedBufLen?.pointee = range.length
+        usedBufLen?.pointee = encodingView.count
+        convertedLength = encodingView.count
         
     case CFStringEncoding(kCFStringEncodingUTF16):
         let encodingView = (str as! NSString)._swiftObject.utf16
@@ -169,13 +168,13 @@
         }
         // Every character was 2 bytes
         usedBufLen?.pointee = range.length * 2
-
+        convertedLength = range.length
 
     default:
         fatalError("Attempted to get bytes of a Swift string using an unsupported encoding")
     }
     
-    return range.length
+    return convertedLength
 }
 
 internal func _CFSwiftStringCreateWithSubstring(_ str: AnyObject, range: CFRange) -> Unmanaged<AnyObject> {
diff --git a/Foundation/NSDecimal.swift b/Foundation/NSDecimal.swift
index 470c55e..dcba6f4 100644
--- a/Foundation/NSDecimal.swift
+++ b/Foundation/NSDecimal.swift
@@ -1,155 +1,1905 @@
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Copyright (c) 2016 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
 //
 
-public var NSDecimalMaxSize: Int32 { NSUnimplemented() }
+import CoreFoundation
+
+public var NSDecimalMaxSize: Int32 { return 8 }
 // Give a precision of at least 38 decimal digits, 128 binary positions.
 
-public var NSDecimalNoScale: Int32 { NSUnimplemented() }
+public var NSDecimalNoScale: Int32 { return Int32(Int16.max) }
 
 public struct Decimal {
-    public var _exponent: Int32
-    public var _length: UInt32 // length == 0 && isNegative -> NaN
-    public var _isNegative: UInt32
-    public var _isCompact: UInt32
-    public var _reserved: UInt32
+    fileprivate static let maxSize: UInt32 = UInt32(NSDecimalMaxSize)
+    fileprivate var __exponent: Int8
+    fileprivate var __lengthAndFlags: UInt8
+    fileprivate var __reserved: UInt16
+    public var _exponent: Int32 {
+        get {
+            return Int32(__exponent)
+        }
+        set {
+            __exponent = Int8(truncatingBitPattern: newValue)
+        }
+    }
+    // length == 0 && isNegative -> NaN
+    public var _length: UInt32 {
+        get {
+            return UInt32((__lengthAndFlags & 0b0000_1111))
+        }
+        set {
+            guard newValue <= maxMantissaLength else {
+                fatalError("Attempt to set a length greater than capacity \(newValue) > \(maxMantissaLength)")
+            }
+            __lengthAndFlags =
+                (__lengthAndFlags & 0b1111_0000) |
+                UInt8(newValue & 0b0000_1111)
+        }
+    }
+    public var _isNegative: UInt32 {
+        get {
+            return UInt32(((__lengthAndFlags) & 0b0001_0000) >> 4)
+        }
+        set {
+            __lengthAndFlags =
+                (__lengthAndFlags & 0b1110_1111) |
+                (UInt8(newValue & 0b0000_0001 ) << 4)
+        }
+    }
+    public var _isCompact: UInt32 {
+        get {
+            return UInt32(((__lengthAndFlags) & 0b0010_0000) >> 5)
+        }
+        set {
+            __lengthAndFlags =
+                (__lengthAndFlags & 0b1101_1111) |
+                (UInt8(newValue & 0b0000_00001 ) << 5)
+        }
+    }
+    public var _reserved: UInt32 {
+        get {
+            return UInt32(UInt32(__lengthAndFlags & 0b1100_0000) << 10 | UInt32(__reserved))
+        }
+        set {
+            __lengthAndFlags =
+                (__lengthAndFlags & 0b0011_1111) |
+                UInt8(UInt32(newValue & (0b11 << 16)) >> 10)
+            __reserved = UInt16(newValue & 0b1111_1111_1111_1111)
+        }
+    }
     public var _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
-    public init() { NSUnimplemented() }
-    public init(_exponent: Int32, _length: UInt32, _isNegative: UInt32, _isCompact: UInt32, _reserved: UInt32, _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)){ NSUnimplemented() }
+    public init() {
+        self._mantissa = (0,0,0,0,0,0,0,0)
+        self.__exponent = 0
+        self.__lengthAndFlags = 0
+        self.__reserved = 0
+    }
+
+    fileprivate init(length: UInt32, mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)) {
+        self._mantissa = mantissa
+        self.__exponent = 0
+        self.__lengthAndFlags = 0
+        self.__reserved = 0
+        self._length = length
+    }
+
+    public init(_exponent: Int32, _length: UInt32, _isNegative: UInt32, _isCompact: UInt32, _reserved: UInt32, _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)){
+        self._mantissa = _mantissa
+        self.__exponent = Int8(truncatingBitPattern: _exponent)
+        self.__lengthAndFlags = UInt8(_length & 0b1111)
+        self.__reserved = 0
+        self._isNegative = _isNegative
+        self._isCompact = _isCompact
+        self._reserved = _reserved
+    }
 }
 
 extension Decimal {
-    // These will need to be `let`s when implemented for Foundation API compatibility
-    public static var leastFiniteMagnitude: Decimal { NSUnimplemented() }
-    public static var greatestFiniteMagnitude: Decimal { NSUnimplemented() }
-    public static var leastNormalMagnitude: Decimal { NSUnimplemented() }
-    public static var leastNonzeroMagnitude: Decimal { NSUnimplemented() }
-    public static var pi: Decimal { NSUnimplemented() }
-    public var exponent: Int { NSUnimplemented() }
-    public var significand: Decimal { NSUnimplemented() }
-    public init(sign: FloatingPointSign, exponent: Int, significand: Decimal) { NSUnimplemented() }
-    public init(signOf: Decimal, magnitudeOf magnitude: Decimal) { NSUnimplemented() }
-    public var sign: FloatingPointSign { NSUnimplemented() }
-    public static var radix: Int { NSUnimplemented() }
-    public var ulp: Decimal { NSUnimplemented() }
-    public mutating func add(_ other: Decimal) { NSUnimplemented() }
-    public mutating func subtract(_ other: Decimal) { NSUnimplemented() }
-    public mutating func multiply(by other: Decimal) { NSUnimplemented() }
-    public mutating func divide(by other: Decimal) { NSUnimplemented() }
-    public mutating func negate() { NSUnimplemented() }
-    public func isEqual(to other: Decimal) -> Bool { NSUnimplemented() }
-    public func isLess(than other: Decimal) -> Bool { NSUnimplemented() }
-    public func isLessThanOrEqualTo(_ other: Decimal) -> Bool { NSUnimplemented() }
-    public func isTotallyOrdered(belowOrEqualTo other: Decimal) -> Bool { NSUnimplemented() }
-    public var isCanonical: Bool { NSUnimplemented() }
-    public var nextUp: Decimal { NSUnimplemented() }
-    public var nextDown: Decimal { NSUnimplemented() }
-    public static func +(lhs: Decimal, rhs: Decimal) -> Decimal { NSUnimplemented() }
-    public static func -(lhs: Decimal, rhs: Decimal) -> Decimal { NSUnimplemented() }
-    public static func /(lhs: Decimal, rhs: Decimal) -> Decimal { NSUnimplemented() }
-    public static func *(lhs: Decimal, rhs: Decimal) -> Decimal { NSUnimplemented() }
+    public static let leastFiniteMagnitude = Decimal(
+        _exponent: 127,
+        _length: 8,
+        _isNegative: 1,
+        _isCompact: 1,
+        _reserved: 0,
+        _mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
+    )
+    public static let greatestFiniteMagnitude = Decimal(
+        _exponent: 127,
+        _length: 8,
+        _isNegative: 0,
+        _isCompact: 1,
+        _reserved: 0,
+        _mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
+    )
+    public static let leastNormalMagnitude = Decimal(
+        _exponent: -127,
+        _length: 1,
+        _isNegative: 0,
+        _isCompact: 1,
+        _reserved: 0,
+        _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
+    )
+    public static let leastNonzeroMagnitude = Decimal(
+        _exponent: -127,
+        _length: 1,
+        _isNegative: 0,
+        _isCompact: 1,
+        _reserved: 0,
+        _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
+    )
+    public static let pi = Decimal(
+        _exponent: -38,
+        _length: 8,
+        _isNegative: 0,
+        _isCompact: 1,
+        _reserved: 0,
+        _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58)
+    )
+    public var exponent: Int {
+        get {
+            return Int(self.__exponent)
+        }
+    }
+    public var significand: Decimal {
+        get {
+            return Decimal(_exponent: 0, _length: _length, _isNegative: _isNegative, _isCompact: _isCompact, _reserved: 0, _mantissa: _mantissa)
+        }
+    }
+    public init(sign: FloatingPointSign, exponent: Int, significand: Decimal) {
+        self.init(_exponent: Int32(exponent) + significand._exponent, _length: significand._length, _isNegative: sign == .plus ? 0 : 1, _isCompact: significand._isCompact, _reserved: 0, _mantissa: significand._mantissa)
+    }
+    public init(signOf: Decimal, magnitudeOf magnitude: Decimal) {
+        self.init(_exponent: magnitude._exponent, _length: magnitude._length, _isNegative: signOf._isNegative, _isCompact: magnitude._isCompact, _reserved: 0, _mantissa: magnitude._mantissa)
+    }
+    public var sign: FloatingPointSign {
+        return _isNegative == 0 ? FloatingPointSign.plus : FloatingPointSign.minus
+    }
+    public static var radix: Int {
+        return 10
+    }
+    public var ulp: Decimal {
+        if !self.isFinite { return Decimal.nan }
+        return Decimal(_exponent: _exponent, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
+    }
+    public mutating func add(_ other: Decimal) {
+        var rhs = other
+        _ = NSDecimalAdd(&self, &self, &rhs, .plain)
+    }
+    public mutating func subtract(_ other: Decimal) {
+        var rhs = other
+        _ = NSDecimalSubtract(&self, &self, &rhs, .plain)
+    }
+    public mutating func multiply(by other: Decimal) {
+        var rhs = other
+        _ = NSDecimalMultiply(&self, &self, &rhs, .plain)
+    }
+    public mutating func divide(by other: Decimal) {
+        var rhs = other
+        _ = NSDecimalDivide(&self, &self, &rhs, .plain)
+    }
+    public mutating func negate() {
+        _isNegative = _isNegative == 0 ? 1 : 0
+    }
+    public func isEqual(to other: Decimal) -> Bool {
+        return self.compare(to: other) == .orderedSame
+    }
+    public func isLess(than other: Decimal) -> Bool {
+        return self.compare(to: other) == .orderedAscending
+    }
+    public func isLessThanOrEqualTo(_ other: Decimal) -> Bool {
+        let comparison = self.compare(to: other)
+        return comparison == .orderedAscending || comparison == .orderedSame
+    }
+    public func isTotallyOrdered(belowOrEqualTo other: Decimal) -> Bool {
+        // Notes: Decimal does not have -0 or infinities to worry about
+        if self.isNaN {
+            return false
+        } else if self < other {
+            return true
+        } else if other < self {
+            return false
+        }
+        // fall through to == behavior
+        return true
+    }
+    public var isCanonical: Bool {
+        return true
+    }
+    public var nextUp: Decimal {
+        return self + Decimal(_exponent: _exponent, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
+    }
+    public var nextDown: Decimal {
+        return self - Decimal(_exponent: _exponent, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
+    }
+    public static func +(lhs: Decimal, rhs: Decimal) -> Decimal {
+        var answer = lhs
+        answer.add(rhs)
+        return answer;
+    }
+    public static func -(lhs: Decimal, rhs: Decimal) -> Decimal {
+        var answer = lhs
+        answer.subtract(rhs)
+        return answer;
+    }
+    public static func /(lhs: Decimal, rhs: Decimal) -> Decimal {
+        var answer = lhs
+        answer.divide(by: rhs)
+        return answer;
+    }
+    public static func *(lhs: Decimal, rhs: Decimal) -> Decimal {
+        var answer = lhs
+        answer.multiply(by: rhs)
+        return answer;
+    }
 }
 
 extension Decimal : Hashable, Comparable {
-    public var hashValue: Int { NSUnimplemented() }
-    public static func ==(lhs: Decimal, rhs: Decimal) -> Bool { NSUnimplemented() }
-    public static func <(lhs: Decimal, rhs: Decimal) -> Bool { NSUnimplemented() }
+    internal var doubleValue: Double {
+        var d = 0.0
+        if _length == 0 && _isNegative == 0 {
+            return Double.nan
+        }
+        for i in 0..<8 {
+            let index = 8 - i - 1
+            switch index {
+            case 0:
+                d = d * 65536 + Double(_mantissa.0)
+                break
+            case 1:
+                d = d * 65536 + Double(_mantissa.1)
+                break
+            case 2:
+                d = d * 65536 + Double(_mantissa.2)
+                break
+            case 3:
+                d = d * 65536 + Double(_mantissa.3)
+                break
+            case 4:
+                d = d * 65536 + Double(_mantissa.4)
+                break
+            case 5:
+                d = d * 65536 + Double(_mantissa.5)
+                break
+            case 6:
+                d = d * 65536 + Double(_mantissa.6)
+                break
+            case 7:
+                d = d * 65536 + Double(_mantissa.7)
+                break
+            default:
+                fatalError("conversion overflow")
+            }
+        }
+        if _exponent < 0 {
+            for _ in _exponent..<0 {
+                d /= 10.0
+            }
+        } else {
+            for _ in 0..<_exponent {
+                d *= 10.0
+            }
+        }
+        return _isNegative != 0 ? -d : d
+    }
+    public var hashValue: Int {
+        return Int(bitPattern: __CFHashDouble(doubleValue))
+    }
+    public static func ==(lhs: Decimal, rhs: Decimal) -> Bool {
+        if lhs.isNaN {
+            return rhs.isNaN
+        }
+        if lhs.__exponent == rhs.__exponent && lhs.__lengthAndFlags == rhs.__lengthAndFlags && lhs.__reserved == rhs.__reserved {
+            if lhs._mantissa.0 == rhs._mantissa.0 &&
+                lhs._mantissa.1 == rhs._mantissa.1 &&
+                lhs._mantissa.2 == rhs._mantissa.2 &&
+                lhs._mantissa.3 == rhs._mantissa.3 &&
+                lhs._mantissa.4 == rhs._mantissa.4 &&
+                lhs._mantissa.5 == rhs._mantissa.5 &&
+                lhs._mantissa.6 == rhs._mantissa.6 &&
+                lhs._mantissa.7 == rhs._mantissa.7 {
+                return true
+            }
+        }
+        var lhsVal = lhs
+        var rhsVal = rhs
+        return NSDecimalCompare(&lhsVal, &rhsVal) == .orderedSame
+    }
+    public static func <(lhs: Decimal, rhs: Decimal) -> Bool {
+        var lhsVal = lhs
+        var rhsVal = rhs
+        return NSDecimalCompare(&lhsVal, &rhsVal) == .orderedAscending
+    }
 }
 
 extension Decimal : ExpressibleByFloatLiteral {
-    public init(floatLiteral value: Double) { NSUnimplemented() }
+    public init(floatLiteral value: Double) {
+        self.init(value)
+    }
 }
 
 extension Decimal : ExpressibleByIntegerLiteral {
-    public init(integerLiteral value: Int) { NSUnimplemented() }
+    public init(integerLiteral value: Int) {
+        self.init(value)
+    }
 }
 
 extension Decimal : SignedNumber {
 }
 
 extension Decimal : Strideable {
-    public func distance(to other: Decimal) -> Decimal { NSUnimplemented() }
-    public func advanced(by n: Decimal) -> Decimal { NSUnimplemented() }
+    public func distance(to other: Decimal) -> Decimal {
+        return self - other
+    }
+    public func advanced(by n: Decimal) -> Decimal {
+        return self + n
+    }
 }
 
 extension Decimal : AbsoluteValuable {
-    public static func abs(_ x: Decimal) -> Decimal { NSUnimplemented() }
+    public static func abs(_ x: Decimal) -> Decimal {
+        return Decimal(_exponent: x._exponent, _length: x._length, _isNegative: 0, _isCompact: x._isCompact, _reserved: 0, _mantissa: x._mantissa)
+    }
 }
 
 extension Decimal {
     public typealias RoundingMode = NSDecimalNumber.RoundingMode
     public typealias CalculationError = NSDecimalNumber.CalculationError
-    public init(_ value: UInt8) { NSUnimplemented() }
-    public init(_ value: Int8) { NSUnimplemented() }
-    public init(_ value: UInt16) { NSUnimplemented() }
-    public init(_ value: Int16) { NSUnimplemented() }
-    public init(_ value: UInt32) { NSUnimplemented() }
-    public init(_ value: Int32) { NSUnimplemented() }
-    public init(_ value: Double) { NSUnimplemented() }
-    public init(_ value: UInt64) { NSUnimplemented() }
-    public init(_ value: Int64) { NSUnimplemented() }
-    public init(_ value: UInt) { NSUnimplemented() }
-    public init(_ value: Int) { NSUnimplemented() }
-    public var isSignalingNaN: Bool { NSUnimplemented() }
-    public static var nan: Decimal { NSUnimplemented() }
-    public static var quietNaN: Decimal { NSUnimplemented() }
-    public var floatingPointClass: FloatingPointClassification { NSUnimplemented() }
-    public var isSignMinus: Bool { NSUnimplemented() }
-    public var isNormal: Bool { NSUnimplemented() }
-    public var isFinite: Bool { NSUnimplemented() }
-    public var isZero: Bool { NSUnimplemented() }
-    public var isSubnormal: Bool { NSUnimplemented() }
-    public var isInfinite: Bool { NSUnimplemented() }
-    public var isNaN: Bool { NSUnimplemented() }
-    public var isSignaling: Bool { NSUnimplemented() }
+    public init(_ value: UInt8) {
+        self.init(UInt64(value))
+    }
+    public init(_ value: Int8) {
+        self.init(Int64(value))
+    }
+    public init(_ value: UInt16) {
+        self.init(UInt64(value))
+    }
+    public init(_ value: Int16) {
+        self.init(Int64(value))
+    }
+    public init(_ value: UInt32) {
+        self.init(UInt64(value))
+    }
+    public init(_ value: Int32) {
+        self.init(Int64(value))
+    }
+    public init(_ value: Double) {
+        if value.isNaN {
+            self = Decimal.nan
+        } else if value == 0.0 {
+            self = Decimal()
+        } else {
+            self = Decimal()
+            let negative = value < 0
+            var val = negative ? -1 * value : value
+            var exponent = 0
+            while val < Double(UInt64.max - 1) {
+                val *= 10.0
+                exponent -= 1
+            }
+            while Double(UInt64.max - 1) < val {
+                val /= 10.0
+                exponent += 1
+            }
+            var mantissa = UInt64(val)
+
+            var i = Int32(0)
+            // this is a bit ugly but it is the closest approximation of the C initializer that can be expressed here.
+            while mantissa != 0 && i < NSDecimalMaxSize {
+                switch i {
+                case 0:
+                    _mantissa.0 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 1:
+                    _mantissa.1 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 2:
+                    _mantissa.2 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 3:
+                    _mantissa.3 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 4:
+                    _mantissa.4 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 5:
+                    _mantissa.5 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 6:
+                    _mantissa.6 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                case 7:
+                    _mantissa.7 = UInt16(truncatingBitPattern:mantissa)
+                    break
+                default:
+                    fatalError("initialization overflow")
+                }
+                mantissa = mantissa >> 16
+                i += 1
+            }
+            _length = UInt32(i)
+            _isNegative = negative ? 1 : 0
+            _isCompact = 0
+            _exponent = Int32(exponent)
+            self.compact()
+        }
+    }
+    public init(_ value: UInt64) {
+        self.init(Double(value))
+    }
+    public init(_ value: Int64) {
+        self.init(Double(value))
+    }
+    public init(_ value: UInt) {
+        self.init(UInt64(value))
+    }
+    public init(_ value: Int) {
+        self.init(Int64(value))
+    }
+    public var isSignalingNaN: Bool {
+        return false
+    }
+    public static var nan: Decimal {
+        return quietNaN
+    }
+    public static var quietNaN: Decimal {
+        var quiet = Decimal()
+        quiet._isNegative = 1
+        return quiet
+    }
+    public var floatingPointClass: FloatingPointClassification {
+        if _length == 0 && _isNegative == 1 {
+            return .quietNaN
+        } else if _length == 0 {
+            return .positiveZero
+        }
+        if _isNegative == 1 {
+            return .negativeNormal
+        } else {
+            return .positiveNormal
+        }
+    }
+    public var isSignMinus: Bool {
+        return _isNegative != 0
+    }
+    public var isNormal: Bool {
+        return !isZero && !isInfinite && !isNaN
+    }
+    public var isFinite: Bool {
+        return !isNaN
+    }
+    public var isZero: Bool {
+        return _length == 0 && _isNegative == 0
+    }
+    public var isSubnormal: Bool {
+        return false
+    }
+    public var isInfinite: Bool {
+        return false
+    }
+    public var isNaN: Bool {
+        return _length == 0 && _isNegative == 1
+    }
+    public var isSignaling: Bool {
+        return false
+    }
 }
 
 extension Decimal : CustomStringConvertible {
     public init?(string: String, locale: Locale? = nil) {
-        // Avoid a compiler warning for now by not calling NSUnimplemented
-        return nil
+        let scan = Scanner(string: string)
+        var theDecimal = Decimal()
+        if !scan.scanDecimal(&theDecimal) {
+            return nil
+        }
+        self = theDecimal
     }
-    public var description: String { NSUnimplemented() }
+    public var description: String {
+        if self.isNaN {
+            return "NaN"
+        }
+        if _length == 0 {
+            return "0"
+        }
+        var copy = self
+        let ZERO : CChar = 0x30 // ASCII '0' == 0x30
+        let decimalChar : CChar = 0x2e // ASCII '.' == 0x2e
+        let MINUS : CChar = 0x2d // ASCII '-' == 0x2d
+
+        let bufferSize = 200 // max value : 39+128+sign+decimalpoint
+        var buffer = Array<CChar>(repeating: 0, count: bufferSize)
+
+        var i = bufferSize - 1
+        while copy._exponent > 0 {
+            i -= 1
+            buffer[i] = ZERO
+            copy._exponent -= 1
+        }
+
+        if copy._exponent == 0 {
+            copy._exponent = 1
+        }
+
+        while copy._length != 0 {
+            var remainder: UInt16 = 0
+            if copy._exponent == 0 {
+                i -= 1
+                buffer[i] = decimalChar
+            }
+            copy._exponent += 1
+            (remainder,_) = divideByShort(&copy, 10)
+            i -= 1
+            buffer[i] = Int8(remainder) + ZERO
+        }
+        if copy._exponent <= 0 {
+            while copy._exponent != 0 {
+                i -= 1
+                buffer[i] = ZERO
+                copy._exponent += 1
+            }
+            i -= 1
+            buffer[i] = decimalChar
+            i -= 1
+            buffer[i] = ZERO
+        }
+        if copy._isNegative != 0 {
+            i -= 1
+            buffer[i] = MINUS
+        }
+        return String(cString: Array(buffer.suffix(from:i)))
+    }
 }
 
-public func NSDecimalIsNotANumber(_ dcm: UnsafePointer<Decimal>) -> Bool { NSUnimplemented() }
+fileprivate func divideByShort<T:VariableLengthNumber>(_ d: inout T, _ divisor:UInt16) -> (UInt16,NSDecimalNumber.CalculationError) {
+    if divisor == 0 {
+        d._length = 0
+        return (0,.divideByZero)
+    }
+    // note the below is not the same as from length to 0 by -1
+    var carry: UInt32 = 0
+    for i in (0..<d._length).reversed() {
+        let accumulator = UInt32(d[i]) + carry * (1<<16)
+        d[i] = UInt16(accumulator / UInt32(divisor))
+        carry = accumulator % UInt32(divisor)
+    }
+    d.trimTrailingZeros()
+    return (UInt16(carry),.noError)
+}
 
+fileprivate func multiplyByShort<T:VariableLengthNumber>(_ d: inout T, _ mul:UInt16) -> NSDecimalNumber.CalculationError {
+    if mul == 0 {
+        d._length = 0
+        return .noError
+    }
+    var carry: UInt32 = 0
+    // FIXME handle NSCalculationOverflow here?
+    for i in 0..<d._length {
+        let accumulator: UInt32 = UInt32(d[i]) * UInt32(mul) + carry
+        carry = accumulator >> 16
+        d[i] = UInt16(truncatingBitPattern: accumulator)
+    }
+    if carry != 0 {
+        if d._length >= Decimal.maxSize {
+            return .overflow
+        }
+        d[d._length] = UInt16(truncatingBitPattern: carry)
+        d._length += 1
+    }
+    return .noError
+}
+
+fileprivate func addShort<T:VariableLengthNumber>(_ d: inout T, _ add:UInt16) -> NSDecimalNumber.CalculationError {
+    var carry:UInt32 = UInt32(add)
+    for i in 0..<d._length {
+        let accumulator: UInt32 = UInt32(d[i]) + carry
+        carry = accumulator >> 16
+        d[i] = UInt16(truncatingBitPattern: accumulator)
+    }
+    if carry != 0 {
+        if d._length >= Decimal.maxSize {
+            return .overflow
+        }
+        d[d._length] = UInt16(truncatingBitPattern: carry)
+        d._length += 1
+    }
+    return .noError
+}
+
+public func NSDecimalIsNotANumber(_ dcm: UnsafePointer<Decimal>) -> Bool {
+	return dcm.pointee.isNaN
+}
 
 /***************	Operations		***********/
-public func NSDecimalCopy(_ destination: UnsafeMutablePointer<Decimal>, _ source: UnsafePointer<Decimal>) { NSUnimplemented() }
+public func NSDecimalCopy(_ destination: UnsafeMutablePointer<Decimal>, _ source: UnsafePointer<Decimal>) {
+    destination.pointee.__lengthAndFlags = source.pointee.__lengthAndFlags
+    destination.pointee.__exponent = source.pointee.__exponent
+    destination.pointee.__reserved = source.pointee.__reserved
+    destination.pointee._mantissa = source.pointee._mantissa
+}
 
-public func NSDecimalCompact(_ number: UnsafeMutablePointer<Decimal>) { NSUnimplemented() }
+public func NSDecimalCompact(_ number: UnsafeMutablePointer<Decimal>) {
+    number.pointee.compact()
+}
 
-public func NSDecimalCompare(_ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>) -> ComparisonResult { NSUnimplemented() }
 // NSDecimalCompare:Compares leftOperand and rightOperand.
+public func NSDecimalCompare(_ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>) -> ComparisonResult {
+    let left = leftOperand.pointee
+    let right = rightOperand.pointee
+    return left.compare(to: right)
+}
 
-public func NSDecimalRound(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ scale: Int, _ roundingMode: NSDecimalNumber.RoundingMode) { NSUnimplemented() }
+fileprivate extension UInt16 {
+    func compareTo(_ other: UInt16) -> ComparisonResult {
+        if self < other {
+            return .orderedAscending
+        } else if self > other {
+            return .orderedDescending
+        } else {
+            return .orderedSame
+        }
+    }
+}
+
+fileprivate func decimalCompare<T:VariableLengthNumber>(
+    _ left: T,
+    _ right: T) -> ComparisonResult {
+
+    if left._length > right._length {
+        return .orderedDescending
+    }
+    if left._length < right._length {
+        return .orderedAscending
+    }
+    let length = left._length // == right._length
+    for i in 0..<length {
+        let comparison = left[i].compareTo(right[i])
+        if comparison != .orderedSame {
+            return comparison
+        }
+    }
+    return .orderedSame
+}
+
+fileprivate func fitMantissa(_ big: inout WideDecimal, _ exponent: inout Int32, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+
+    if big._length <= Decimal.maxSize {
+        return .noError
+    }
+
+    var remainder: UInt16 = 0
+    var previousRemainder: Bool = false
+
+    // Divide by 10 as much as possible
+    while big._length > Decimal.maxSize + 1 {
+        if remainder != 0 {
+            previousRemainder = true
+        }
+        (remainder,_) = divideByShort(&big,10000)
+        exponent += 4
+    }
+
+    while big._length > Decimal.maxSize {
+        if remainder != 0 {
+            previousRemainder = true
+        }
+        (remainder,_) = divideByShort(&big,10)
+        exponent += 1
+    }
+
+    // If we are on a tie, adjust with previous remainder.
+    // .50001 is equivalent to .6
+    if previousRemainder && (remainder == 0 || remainder == 5) {
+        remainder += 1
+    }
+
+    if remainder == 0 {
+        return .noError
+    }
+
+    // Round the result
+    switch roundingMode  {
+    case .down:
+        break
+    case .bankers:
+        if remainder == 5 && (big[0] & 1) == 0 {
+            break
+        }
+        fallthrough
+    case .plain:
+        if remainder < 5 {
+            break
+        }
+        fallthrough
+    case .up:
+        let originalLength = big._length
+        // big._length += 1 ??
+        _ = addShort(&big,1)
+        if originalLength > big._length {
+            // the last digit is == 0. Remove it.
+            _ = divideByShort(&big, 10)
+            exponent += 1
+        }
+    }
+    return .lossOfPrecision;
+}
+
+fileprivate func integerMultiply<T:VariableLengthNumber>(_ big: inout T,
+                                 _ left: T,
+                                 _ right: Decimal) -> NSDecimalNumber.CalculationError {
+    if left._length == 0 || right._length == 0 {
+        big._length = 0
+        return .noError
+    }
+
+    if big._length == 0 || big._length > left._length + right._length {
+        big._length = min(big.maxMantissaLength,left._length + right._length)
+    }
+
+    big.zeroMantissa()
+
+    var carry: UInt16 = 0
+
+    for j in 0..<right._length {
+        var accumulator: UInt32 = 0
+        carry = 0
+
+        for i in 0..<left._length {
+            if i + j < big._length {
+                let bigij = UInt32(big[i+j])
+                accumulator = UInt32(carry) + bigij + UInt32(right[j]) * UInt32(left[i])
+                carry = UInt16(truncatingBitPattern:accumulator >> UInt32(16))
+                big[i+j] = UInt16(truncatingBitPattern:accumulator)
+            } else if carry != 0 || (right[j] == 0 && left[j] == 0) {
+                return .overflow
+            }
+        }
+
+        if carry != 0 {
+            if left._length + j < big._length {
+                big[left._length + j] = carry
+            } else {
+                return .overflow
+            }
+        }
+    }
+
+    big.trimTrailingZeros()
+
+    return .noError
+}
+
+fileprivate func integerDivide<T:VariableLengthNumber>(_ r: inout T,
+                               _ cu: T,
+                               _ cv: Decimal) -> NSDecimalNumber.CalculationError {
+    // Calculate result = a / b.
+    // Result could NOT be a pointer to same space as a or b.
+    // resultLen must be >= aLen - bLen.
+    //
+    // Based on algorithm in The Art of Computer Programming, Volume 2,
+    // Seminumerical Algorithms by Donald E. Knuth, 2nd Edition. In addition
+    // you need to consult the erratas for the book available at:
+    //
+    //   http://www-cs-faculty.stanford.edu/~uno/taocp.html
+
+    var u = WideDecimal(true)
+    var v = WideDecimal(true) // divisor
+
+    // Simple case
+    if cv.isZero {
+        return .divideByZero;
+    }
+
+    // If u < v, the result is approximately 0...
+    if cu._length < cv._length {
+        for i in 0..<cv._length {
+            if cu[i] < cv[i] {
+                r._length = 0
+                return .noError;
+            }
+        }
+    }
+
+    // Fast algorithm
+    if cv._length == 1 {
+        r = cu
+        let (_,error) = divideByShort(&r, cv[0])
+        return error
+    }
+
+    u.copyMantissa(from: cu)
+    v.copyMantissa(from: cv)
+
+    u._length = cu._length + 1
+    v._length = cv._length + 1
+
+    // D1: Normalize
+    // Calculate d such that d*highest_digit of v >= b/2 (0x8000)
+    //
+    // I could probably use something smarter to get d to be a power of 2.
+    // In this case the multiply below became only a shift.
+    let d: UInt32 = UInt32((1 << 16) / Int(cv[cv._length - 1] + 1))
+
+    // This is to make the whole algorithm work and u*d/v*d == u/v
+    _ = multiplyByShort(&u, UInt16(d))
+    _ = multiplyByShort(&v, UInt16(d))
+
+    u.trimTrailingZeros()
+    v.trimTrailingZeros()
+
+    // Set a zero at the leftmost u position if the multiplication
+    // does not have a carry.
+    if u._length == cu._length {
+        u[u._length] = 0
+        u._length += 1
+    }
+
+    v[v._length] = 0; // Set a zero at the leftmost v position.
+    // the algorithm will use it during the
+    // multiplication/subtraction phase.
+
+    // Determine the size of the quotient.
+    // It's an approximate value.
+    let ql:UInt16 = UInt16(u._length - v._length)
+
+    // Some useful constants for the loop
+    // It's used to determine the quotient digit as fast as possible
+    // The test vl > 1 is probably useless, since optimizations
+    // up there are taking over this case. I'll keep it, just in case.
+    let v1:UInt16 = v[v._length-1]
+    let v2:UInt16 = v._length > 1 ? v[v._length-2] : 0
+
+    // D2: initialize j
+    // On each pass, build a single value for the quotient.
+    for j in 0..<ql {
+
+        // D3: calculate q^
+        // This formula and test for q gives at most q+1; See Knuth for proof.
+
+        let ul = u._length
+        let tmp:UInt32 = UInt32(u[ul - UInt32(j) - UInt32(1)]) << 16 + UInt32(u[ul - UInt32(j) - UInt32(2)])
+        var q:UInt32 = tmp / UInt32(v1) // Quotient digit. could be a short.
+        var rtmp:UInt32 = tmp % UInt32(v1)
+
+        // This test catches all cases where q is really q+2 and
+        // most where it is q+1
+        if q == (1 << 16) || UInt32(v2) * q > (rtmp<<16) + UInt32(u[ul - UInt32(j) - UInt32(3)]) {
+            q -= 1
+            rtmp += UInt32(v1)
+
+            if (rtmp < (1 << 16)) && ( (q == (1 << 16) ) || ( UInt32(v2) * q > (rtmp<<16) + UInt32(u[ul - UInt32(j) - UInt32(3)])) ) {
+                q -= 1
+                rtmp += UInt32(v1)
+            }
+        }
+
+        // D4: multiply and subtract.
+
+        var mk:UInt32 = 0 // multiply carry
+        var sk:UInt32 = 1 // subtraction carry
+        var acc:UInt32
+
+        // We perform a multiplication and a subtraction
+        // during the same pass...
+        for i in 0...v._length {
+            let ul = u._length
+            let vl = v._length
+            acc = q * UInt32(v[i]) + mk     // multiply
+            mk = acc >> 16                  // multiplication carry
+            acc = acc & 0xffff;
+            acc = 0xffff + UInt32(u[ul - vl + i - UInt32(j) - UInt32(1)]) - acc + sk; // subtract
+            sk = acc >> 16;
+            u[ul - vl + i - UInt32(j) - UInt32(1)] = UInt16(truncatingBitPattern:acc)
+        }
+
+        // D5: test remainder
+        // This test catches cases where q is still q + 1
+        if sk == 0 {
+            // D6: add back.
+            var k:UInt32 = 0 // Addition carry
+
+            // subtract one from the quotient digit
+            q -= 1
+            for i in 0...v._length {
+                let ul = u._length
+                let vl = v._length
+                acc = UInt32(v[i]) + UInt32(u[UInt32(ul) - UInt32(vl) + UInt32(i) - UInt32(j) - UInt32(1)]) + k
+                k = acc >> 16;
+                u[UInt32(ul) - UInt32(vl) + UInt32(i) - UInt32(j) - UInt32(1)] = UInt16(truncatingBitPattern:acc)
+            }
+            // k must be == 1 here
+        }
+
+        r[UInt32(ql - j - UInt16(1))] = UInt16(q)
+        // D7: loop on j
+    }
+
+    r._length = UInt32(ql);
+
+    r.trimTrailingZeros()
+
+    return .noError;
+}
+
+fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: inout T, _ left: T, _ p: Int) -> NSDecimalNumber.CalculationError {
+    var power = p
+    if power == 0 {
+        result = left
+        return .noError
+    }
+    let isNegative = power < 0
+    if isNegative {
+        power = -power
+    }
+    result = left
+
+    let maxpow10 = pow10.count - 1
+    var error:NSDecimalNumber.CalculationError = .noError
+
+    while power > maxpow10 {
+        var big = T()
+
+        power -= maxpow10
+        let p10 = pow10[maxpow10]
+
+        if !isNegative {
+            error = integerMultiply(&big,result,p10)
+        } else {
+            error = integerDivide(&big,result,p10)
+        }
+
+        if error != .noError && error != .lossOfPrecision {
+            return error;
+        }
+
+        for i in 0..<big._length {
+            result[i] = big[i]
+        }
+
+        result._length = big._length
+    }
+
+    var big = T()
+
+    // Handle the rest of the power (<= maxpow10)
+    let p10 = pow10[Int(power)]
+
+    if !isNegative {
+        error = integerMultiply(&big, result, p10)
+    } else {
+        error = integerDivide(&big, result, p10)
+    }
+
+    for i in 0..<big._length {
+        result[i] = big[i]
+    }
+
+    result._length = big._length
+
+    return error;
+}
+
+public func NSDecimalRound(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ scale: Int, _ roundingMode: NSDecimalNumber.RoundingMode) {
+    NSDecimalCopy(result,number) // this is unnecessary if they are the same address, but we can't test that here
+    result.pointee.round(scale: scale,roundingMode: roundingMode)
+}
 // Rounds num to the given scale using the given mode.
 // result may be a pointer to same space as num.
 // scale indicates number of significant digits after the decimal point
 
-public func NSDecimalNormalize(_ number1: UnsafeMutablePointer<Decimal>, _ number2: UnsafeMutablePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+public func NSDecimalNormalize(_ a: UnsafeMutablePointer<Decimal>, _ b: UnsafeMutablePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+    var diffexp = a.pointee.__exponent - b.pointee.__exponent
+    var result = Decimal()
 
-public func NSDecimalAdd(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+    //
+    // If the two numbers share the same exponents,
+    // the normalisation is already done
+    //
+    if diffexp == 0 {
+        return .noError
+    }
+
+    //
+    // Put the smallest of the two in aa
+    //
+    var aa: UnsafeMutablePointer<Decimal>
+    var bb: UnsafeMutablePointer<Decimal>
+
+    if diffexp < 0 {
+        aa = b
+        bb = a
+        diffexp = -diffexp
+    } else {
+        aa = a
+        bb = b
+    }
+
+    //
+    // Build a backup for aa
+    //
+    var backup = Decimal()
+
+    NSDecimalCopy(&backup,aa)
+
+    //
+    // Try to multiply aa to reach the same exponent level than bb
+    //
+
+    if integerMultiplyByPowerOf10(&result, aa.pointee, Int(diffexp)) == .noError {
+        // Succeed. Adjust the length/exponent info
+        // and return no errorNSDecimalNormalize
+        aa.pointee.copyMantissa(from: result)
+        aa.pointee._exponent = bb.pointee._exponent
+        return .noError;
+    }
+
+    //
+    // Failed, restart from scratch
+    //
+    NSDecimalCopy(aa, &backup);
+
+    //
+    // What is the maximum pow10 we can apply to aa ?
+    //
+    let logBase10of2to16 = 4.81647993
+    let aaLength = aa.pointee._length
+    let maxpow10 = Int8(floor(Double(Decimal.maxSize - aaLength) * logBase10of2to16))
+
+    //
+    // Divide bb by this value
+    //
+    _ = integerMultiplyByPowerOf10(&result, bb.pointee, maxpow10 - diffexp)
+
+    bb.pointee.copyMantissa(from: result)
+    bb.pointee._exponent -= maxpow10 - diffexp;
+
+    //
+    // If bb > 0 multiply aa by the same value
+    //
+    if !bb.pointee.isZero {
+        _ = integerMultiplyByPowerOf10(&result, aa.pointee, Int(maxpow10))
+        aa.pointee.copyMantissa(from: result)
+        aa.pointee._exponent -= Int32(maxpow10)
+    } else {
+        bb.pointee._exponent = aa.pointee._exponent;
+    }
+
+    //
+    // the two exponents are now identical, but we've lost some digits in the operation.
+    //
+    return .lossOfPrecision;
+}
+
+public func NSDecimalAdd(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
+        result.pointee.setNaN()
+        return .overflow
+    }
+    if leftOperand.pointee.isZero {
+        NSDecimalCopy(result, rightOperand)
+        return .noError
+    } else if rightOperand.pointee.isZero {
+        NSDecimalCopy(result, leftOperand)
+        return .noError
+    } else {
+        var a = Decimal()
+        var b = Decimal()
+        var error:NSDecimalNumber.CalculationError = .noError
+
+        NSDecimalCopy(&a,leftOperand)
+        NSDecimalCopy(&b,rightOperand)
+
+        let normalizeError = NSDecimalNormalize(&a, &b,roundingMode)
+
+        if a.isZero {
+            NSDecimalCopy(result,&b)
+            return normalizeError
+        }
+        if b.isZero {
+            NSDecimalCopy(result,&a)
+            return normalizeError
+        }
+
+        result.pointee._exponent = a._exponent
+
+        if a.isNegative == b.isNegative {
+            var big = WideDecimal()
+            result.pointee.isNegative = a.isNegative
+
+            // No possible error here.
+            _ = integerAdd(&big,&a,&b)
+
+            if big._length > Decimal.maxSize {
+                var exponent:Int32 = 0
+                error = fitMantissa(&big, &exponent, roundingMode)
+
+                let newExponent = result.pointee._exponent + exponent
+
+                // Just to be sure!
+                if newExponent > Int32(Int8.max) {
+                    result.pointee.setNaN()
+                    return .overflow
+                }
+                result.pointee._exponent = newExponent
+            }
+            let length = min(Decimal.maxSize,big._length)
+            for i in 0..<length {
+                result.pointee[i] = big[i]
+            }
+            result.pointee._length = length
+        } else { // not the same sign
+            let comparison = decimalCompare(a,b)
+
+            switch comparison {
+            case .orderedSame:
+                result.pointee.setZero()
+            case .orderedAscending:
+                _ = integerSubtract(&result.pointee,&b,&a)
+                result.pointee.isNegative = b.isNegative
+            case .orderedDescending:
+                _ = integerSubtract(&result.pointee,&a,&b)
+                result.pointee.isNegative = a.isNegative
+            }
+        }
+        result.pointee._isCompact = 0
+        NSDecimalCompact(result)
+        return error == .noError ? normalizeError : error
+    }
+}
+
+fileprivate func integerAdd(_ result: inout WideDecimal, _ left: inout Decimal, _ right: inout Decimal) -> NSDecimalNumber.CalculationError {
+    var i:UInt32 = 0
+    var carry:UInt16 = 0
+    var accumulator:UInt32 = 0
+
+    let c:UInt32 = min(left._length, right._length)
+
+    while i < c {
+        let li = UInt32(left[i])
+        let ri = UInt32(right[i])
+        accumulator = li + ri + UInt32(carry)
+        carry = UInt16(truncatingBitPattern:accumulator >> 16)
+        result[i] = UInt16(truncatingBitPattern:accumulator)
+        i += 1
+    }
+
+    while i < left._length {
+        if carry != 0 {
+            let li = UInt32(left[i])
+            accumulator = li + UInt32(carry)
+            carry = UInt16(truncatingBitPattern:accumulator >> 16)
+            result[i] = UInt16(truncatingBitPattern:accumulator)
+            i += 1
+        } else {
+            while i < left._length {
+                result[i] = left[i]
+                i += 1
+            }
+            break
+        }
+    }
+    while i < right._length {
+        if carry != 0 {
+            let ri = UInt32(right[i])
+            accumulator = ri + UInt32(carry)
+            carry = UInt16(truncatingBitPattern:accumulator >> 16)
+            result[i] = UInt16(truncatingBitPattern:accumulator)
+            i += 1
+        } else {
+            while i < right._length {
+                result[i] = right[i]
+                i += 1
+            }
+            break
+        }
+    }
+
+    if carry != 0 {
+        if result._length < i {
+            result._length = i
+            return .overflow
+        } else {
+            result[i] = carry
+            i += 1
+        }
+    }
+    result._length = i;
+    return .noError;
+}
+
+// integerSubtract: Subtract b from a, put the result in result, and
+//     modify resultLen to match the length of the result.
+// Result may be a pointer to same space as a or b.
+// resultLen must be >= Max(aLen,bLen).
+// Could return NSCalculationOverflow if b > a. In this case 0 - result
+//    give b-a...
+//
+fileprivate func integerSubtract(_ result: inout Decimal, _ left: inout Decimal, _ right: inout Decimal) -> NSDecimalNumber.CalculationError {
+    var i:UInt32 = 0
+    var carry:UInt16 = 1
+    var accumulator:UInt32 = 0
+
+    let c:UInt32 = min(left._length, right._length)
+
+    while i < c {
+        let li = UInt32(left[i])
+        let ri = UInt32(right[i])
+        accumulator = 0xffff + li - ri + UInt32(carry)
+        carry = UInt16(truncatingBitPattern:accumulator >> 16)
+        result[i] = UInt16(truncatingBitPattern:accumulator)
+        i += 1
+    }
+
+    while i < left._length {
+        if carry != 0 {
+            let li = UInt32(left[i])
+            accumulator = 0xffff + li // + no carry
+            carry = UInt16(truncatingBitPattern:accumulator >> 16)
+            result[i] = UInt16(truncatingBitPattern:accumulator)
+            i += 1
+        } else {
+            while i < left._length {
+                result[i] = left[i]
+                i += 1
+            }
+            break
+        }
+    }
+    while i < right._length {
+        let ri = UInt32(right[i])
+        accumulator = 0xffff - ri + UInt32(carry)
+        carry = UInt16(truncatingBitPattern:accumulator >> 16)
+        result[i] = UInt16(truncatingBitPattern:accumulator)
+        i += 1
+    }
+
+    if carry != 0 {
+        return .overflow
+    }
+    result._length = i;
+
+    result.trimTrailingZeros()
+
+    return .noError;
+}
+
 // Exact operations. result may be a pointer to same space as leftOperand or rightOperand
 
-public func NSDecimalSubtract(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+public func NSDecimalSubtract(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+    var r = rightOperand.pointee
+    if r._length != 0 {
+        r.negate()
+    }
+    return NSDecimalAdd(result, leftOperand, &r, roundingMode)
+}
 // Exact operations. result may be a pointer to same space as leftOperand or rightOperand
 
-public func NSDecimalMultiply(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+public func NSDecimalMultiply(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+
+    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
+        result.pointee.setNaN()
+        return .overflow
+    }
+    if leftOperand.pointee.isZero || rightOperand.pointee.isZero {
+        result.pointee.setZero()
+        return .noError
+    }
+
+    var big = WideDecimal()
+    var calculationError:NSDecimalNumber.CalculationError = .noError
+
+    calculationError = integerMultiply(&big,WideDecimal(leftOperand.pointee),rightOperand.pointee)
+
+    result.pointee._isNegative = (leftOperand.pointee._isNegative + rightOperand.pointee._isNegative) % 2
+
+    var newExponent = leftOperand.pointee._exponent + rightOperand.pointee._exponent
+
+    if big._length > Decimal.maxSize {
+        var exponent:Int32 = 0
+        calculationError = fitMantissa(&big, &exponent, roundingMode)
+        newExponent += exponent
+    }
+
+    for i in 0..<big._length {
+       result.pointee[i] = big[i]
+    }
+    result.pointee._length = big._length
+    result.pointee._isCompact = 0
+
+    if newExponent > Int32(Int8.max) {
+        result.pointee.setNaN()
+        return .overflow
+    }
+    result.pointee._exponent = newExponent
+    NSDecimalCompact(result)
+    return calculationError
+}
 // Exact operations. result may be a pointer to same space as leftOperand or rightOperand
 
-public func NSDecimalDivide(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+public func NSDecimalDivide(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+
+    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
+        result.pointee.setNaN()
+        return .overflow
+    }
+    if rightOperand.pointee.isZero {
+        result.pointee.setNaN()
+        return .divideByZero
+    }
+    if leftOperand.pointee.isZero {
+        result.pointee.setZero()
+        return .noError
+    }
+    var a = Decimal()
+    var b = Decimal()
+    var big = WideDecimal()
+    var exponent:Int32 = 0
+
+    NSDecimalCopy(&a, leftOperand)
+    NSDecimalCopy(&b, rightOperand)
+
+    /* If the precision of the left operand is much smaller
+     * than that of the right operand (for example,
+     * 20 and 0.112314123094856724234234572), then the
+     * difference in their exponents is large and a lot of
+     * precision will be lost below. This is particularly
+     * true as the difference approaches 38 or larger.
+     * Normalizing here looses some precision on the
+     * individual operands, but often produces a more
+     * accurate result later. I chose 19 arbitrarily
+     * as half of the magic 38, so that normalization
+     * doesn't always occur. */
+    if (19 <= a._exponent - b._exponent) {
+        _ = NSDecimalNormalize(&a, &b, roundingMode);
+        /* We ignore the small loss of precision this may
+         * induce in the individual operands. */
+
+        /* Sometimes the normalization done previously is inappropriate and
+         * forces one of the operands to 0. If this happens, restore both. */
+        if a.isZero || b.isZero {
+            NSDecimalCopy(&a, leftOperand);
+            NSDecimalCopy(&b, rightOperand);
+        }
+    }
+
+    _ = integerMultiplyByPowerOf10(&big, WideDecimal(a), 38) // Trust me, it's 38 !
+    _ = integerDivide(&big, big, b)
+    _ = fitMantissa(&big, &exponent, .down)
+
+    let length = min(big._length,Decimal.maxSize)
+    for i in 0..<length {
+        result.pointee[i] = big[i]
+    }
+
+    result.pointee._length = length
+
+    result.pointee.isNegative = a._isNegative != b._isNegative
+
+    exponent = a._exponent - b._exponent - 38 + exponent
+    if exponent < Int32(Int8.min) {
+        result.pointee.setNaN()
+        return .underflow
+    }
+    if exponent > Int32(Int8.max) {
+        result.pointee.setNaN()
+        return .overflow;
+    }
+    result.pointee._exponent = Int32(exponent)
+    result.pointee._isCompact = 0
+    NSDecimalCompact(result)
+    return .noError
+}
 // Division could be silently inexact;
 // Exact operations. result may be a pointer to same space as leftOperand or rightOperand
 
-public func NSDecimalPower(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+public func NSDecimalPower(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
 
-public func NSDecimalMultiplyByPowerOf10(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int16, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError { NSUnimplemented() }
+    if number.pointee.isNaN {
+        result.pointee.setNaN()
+        return .overflow
+    }
+    NSDecimalCopy(result,number)
+    return result.pointee.power(UInt(power), roundingMode:roundingMode)
+}
 
-public func NSDecimalString(_ dcm: UnsafePointer<Decimal>, _ locale: AnyObject?) -> String { NSUnimplemented() }
+public func NSDecimalMultiplyByPowerOf10(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int16, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
+    NSDecimalCopy(result,number)
+    return result.pointee.multiply(byPowerOf10: power)
+}
+
+public func NSDecimalString(_ dcm: UnsafePointer<Decimal>, _ locale: AnyObject?) -> String {
+    guard locale == nil else {
+        fatalError("Locale not supported: \(locale!)")
+    }
+    return dcm.pointee.description
+}
+
+fileprivate protocol VariableLengthNumber {
+    var _length: UInt32 { get set }
+    init()
+    subscript(index:UInt32) -> UInt16 { get set }
+    var isZero:Bool { get }
+    mutating func copyMantissa<T:VariableLengthNumber>(from other:T)
+    mutating func zeroMantissa()
+    mutating func trimTrailingZeros()
+    var maxMantissaLength: UInt32 { get }
+}
+
+extension Decimal: VariableLengthNumber {
+    var maxMantissaLength:UInt32 {
+        return Decimal.maxSize
+    }
+    fileprivate mutating func zeroMantissa() {
+        for i in 0..<Decimal.maxSize {
+            self[i] = 0
+        }
+    }
+    internal mutating func trimTrailingZeros() {
+        if _length > Decimal.maxSize {
+            _length = Decimal.maxSize
+        }
+        while _length != 0 && self[_length - 1] == 0 {
+            _length -= 1
+        }
+    }
+    fileprivate mutating func copyMantissa<T : VariableLengthNumber>(from other: T) {
+        if other._length > maxMantissaLength {
+            for i in maxMantissaLength..<other._length {
+                guard other[i] == 0 else {
+                    fatalError("Loss of precision during copy other[\(i)] \(other[i]) != 0")
+                }
+            }
+        }
+        let length = min(other._length, maxMantissaLength)
+        for i in 0..<length {
+            self[i] = other[i]
+        }
+        self._length = length
+        self._isCompact = 0
+    }
+}
+
+// Provides a way with dealing with extra-length decimals, used for calculations
+fileprivate struct WideDecimal : VariableLengthNumber {
+    var maxMantissaLength:UInt32 {
+        return _extraWide ? 17 : 16
+    }
+
+    fileprivate mutating func zeroMantissa() {
+        for i in 0..<maxMantissaLength {
+            self[i] = 0
+        }
+    }
+    fileprivate mutating func trimTrailingZeros() {
+        while _length != 0 && self[_length - 1] == 0 {
+            _length -= 1
+        }
+    }
+    init() {
+        self.init(false)
+    }
+
+    fileprivate mutating func copyMantissa<T : VariableLengthNumber>(from other: T) {
+        let length = other is Decimal ? min(other._length,Decimal.maxSize) : other._length
+        for i in 0..<length {
+            self[i] = other[i]
+        }
+        self._length = length
+    }
+
+    var isZero: Bool {
+        return _length == 0
+    }
+
+    var __length: UInt16
+    var _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16,
+        UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
+    // Most uses of this class use 16 shorts, but integer division uses 17 shorts
+    var _extraWide: Bool
+    var _length: UInt32 {
+        get {
+            return UInt32(__length)
+        }
+        set {
+            guard newValue <= maxMantissaLength else {
+                fatalError("Attempt to set a length greater than capacity \(newValue) > \(maxMantissaLength)")
+            }
+            __length = UInt16(newValue)
+        }
+    }
+    init(_ extraWide:Bool = false) {
+        __length = 0
+        _mantissa = (UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0))
+        _extraWide = extraWide
+    }
+    init(_ decimal:Decimal) {
+        self.__length = UInt16(decimal._length)
+        self._extraWide = false
+        self._mantissa = (decimal[0],decimal[1],decimal[2],decimal[3],decimal[4],decimal[5],decimal[6],decimal[7],UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0))
+    }
+    subscript(index:UInt32) -> UInt16 {
+        get {
+            switch index {
+            case 0: return _mantissa.0
+            case 1: return _mantissa.1
+            case 2: return _mantissa.2
+            case 3: return _mantissa.3
+            case 4: return _mantissa.4
+            case 5: return _mantissa.5
+            case 6: return _mantissa.6
+            case 7: return _mantissa.7
+            case 8: return _mantissa.8
+            case 9: return _mantissa.9
+            case 10: return _mantissa.10
+            case 11: return _mantissa.11
+            case 12: return _mantissa.12
+            case 13: return _mantissa.13
+            case 14: return _mantissa.14
+            case 15: return _mantissa.15
+            case 16 where _extraWide: return _mantissa.16 // used in integerDivide
+            default: fatalError("Invalid index \(index) for _mantissa")
+            }
+        }
+        set {
+            switch index {
+            case 0: _mantissa.0 = newValue
+            case 1: _mantissa.1 = newValue
+            case 2: _mantissa.2 = newValue
+            case 3: _mantissa.3 = newValue
+            case 4: _mantissa.4 = newValue
+            case 5: _mantissa.5 = newValue
+            case 6: _mantissa.6 = newValue
+            case 7: _mantissa.7 = newValue
+            case 8: _mantissa.8 = newValue
+            case 9: _mantissa.9 = newValue
+            case 10: _mantissa.10 = newValue
+            case 11: _mantissa.11 = newValue
+            case 12: _mantissa.12 = newValue
+            case 13: _mantissa.13 = newValue
+            case 14: _mantissa.14 = newValue
+            case 15: _mantissa.15 = newValue
+            case 16 where _extraWide: _mantissa.16 = newValue
+            default: fatalError("Invalid index \(index) for _mantissa")
+            }
+        }
+    }
+    func toDecimal() -> Decimal {
+        var result = Decimal()
+        result._length = self._length
+        for i in 0..<_length {
+            result[i] = self[i]
+        }
+        return result
+    }
+}
+
+// == Internal (Swifty) functions ==
+
+extension Decimal {
+    fileprivate var isCompact: Bool {
+        get {
+            return _isCompact != 0
+        }
+        set {
+            _isCompact = newValue ? 1 : 0
+        }
+    }
+    fileprivate var isNegative: Bool {
+        get {
+            return _isNegative != 0
+        }
+        set {
+            _isNegative = newValue ? 1 : 0
+        }
+    }
+    fileprivate mutating func compact() {
+        if isCompact || isNaN || _length == 0 {
+            return
+        }
+        var newExponent = self._exponent
+        var remainder: UInt16 = 0
+        // Divide by 10 as much as possible
+        repeat {
+            (remainder,_) = divideByShort(&self,10)
+            newExponent += 1
+        } while remainder == 0
+        // Put the non-empty remainder in place
+        _ = multiplyByShort(&self,10)
+        _ = addShort(&self,remainder)
+        newExponent -= 1
+        // Set the new exponent
+        while newExponent > Int32(Int8.max) {
+            _ = multiplyByShort(&self,10)
+            newExponent -= 1
+        }
+        _exponent = newExponent
+        isCompact = true
+    }
+    fileprivate mutating func round(scale:Int, roundingMode:RoundingMode) {
+        // scale is the number of digits after the decimal point
+        var s = scale + _exponent
+        if s == NSDecimalNoScale || s >= 0 {
+            return
+        }
+        s = -s
+        var remainder: UInt16 = 0
+        var previousRemainder = false
+
+        let negative = _isNegative != 0
+        var newExponent = _exponent + s
+        while s > 4 {
+            if remainder != 0 {
+                previousRemainder = true
+            }
+            (remainder,_) = divideByShort(&self, 10000)
+            s -= 4
+        }
+        while s > 0 {
+            if remainder != 0 {
+                previousRemainder = true
+            }
+            (remainder,_) = divideByShort(&self, 10)
+            s -= 1
+        }
+        // If we are on a tie, adjust with premdr. .50001 is equivalent to .6
+        if previousRemainder && (remainder == 0 || remainder == 5) {
+            remainder += 1;
+        }
+        if remainder != 0 {
+            if negative {
+                switch roundingMode {
+                case .up:
+                    break
+                case .bankers:
+                    if remainder == 5 && (self[0] & 1) == 0 {
+                        remainder += 1
+                    }
+                    fallthrough
+                case .plain:
+                    if remainder < 5 {
+                        break
+                    }
+                    fallthrough
+                case .down:
+                    _ = addShort(&self, 1)
+                }
+                if _length == 0 {
+                    _isNegative = 0;
+                }
+            } else {
+                switch roundingMode {
+                case .down:
+                    break
+                case .bankers:
+                    if remainder == 5 && (self[0] & 1) == 0 {
+                        remainder -= 1
+                    }
+                    fallthrough
+                case .plain:
+                    if remainder < 5 {
+                        break
+                    }
+                    fallthrough
+                case .up:
+                    _ = addShort(&self, 1)
+                }
+            }
+        }
+        _isCompact = 0;
+        
+        while newExponent > Int32(Int8.max) {
+            newExponent -= 1;
+            _ = multiplyByShort(&self, 10);
+        }
+        _exponent = newExponent;
+        self.compact();
+    }
+    internal func compare(to other:Decimal) -> ComparisonResult {
+        // NaN is a special case and is arbitrary ordered before everything else
+        // Conceptually comparing with NaN is bogus anyway but raising or
+        // always returning the same answer will confuse the sorting algorithms
+        if self.isNaN {
+            return other.isNaN ? .orderedSame : .orderedAscending
+        }
+        if other.isNaN {
+            return .orderedDescending
+        }
+        // Check the sign
+        if self._isNegative > other._isNegative {
+            return .orderedAscending
+        }
+        if self._isNegative < other._isNegative {
+            return .orderedDescending
+        }
+        // If one of the two is == 0, the other is bigger
+        // because 0 implies isNegative = 0...
+        if self.isZero && other.isZero {
+            return .orderedSame
+        }
+        if self.isZero {
+            return .orderedAscending
+        }
+        if other.isZero {
+            return .orderedDescending
+        }
+        var selfNormal = self
+        var otherNormal = other
+        _ = NSDecimalNormalize(&selfNormal, &otherNormal, .down)
+        let comparison = decimalCompare(selfNormal,otherNormal)
+        if selfNormal._isNegative == 1 {
+            if comparison == .orderedDescending {
+                return .orderedAscending
+            } else if comparison == .orderedAscending {
+                return .orderedDescending
+            } else {
+                return .orderedSame
+            }
+        }
+        return comparison
+    }
+    fileprivate subscript(index:UInt32) -> UInt16 {
+        get {
+            switch index {
+            case 0: return _mantissa.0
+            case 1: return _mantissa.1
+            case 2: return _mantissa.2
+            case 3: return _mantissa.3
+            case 4: return _mantissa.4
+            case 5: return _mantissa.5
+            case 6: return _mantissa.6
+            case 7: return _mantissa.7
+            default: fatalError("Invalid index \(index) for _mantissa")
+            }
+        }
+        set {
+            switch index {
+            case 0: _mantissa.0 = newValue
+            case 1: _mantissa.1 = newValue
+            case 2: _mantissa.2 = newValue
+            case 3: _mantissa.3 = newValue
+            case 4: _mantissa.4 = newValue
+            case 5: _mantissa.5 = newValue
+            case 6: _mantissa.6 = newValue
+            case 7: _mantissa.7 = newValue
+            default: fatalError("Invalid index \(index) for _mantissa")
+            }
+        }
+    }
+    fileprivate mutating func setNaN() {
+        _length = 0
+        _isNegative = 1
+    }
+    fileprivate mutating func setZero() {
+        _length = 0
+        _isNegative = 0
+    }
+    fileprivate mutating func multiply(byPowerOf10 power:Int16) -> CalculationError {
+        if isNaN {
+            return .overflow
+        }
+        if isZero {
+            return .noError
+        }
+        let newExponent = _exponent + Int32(power)
+        if newExponent < Int32(Int8.min) {
+            setNaN()
+            return .underflow
+        }
+        if newExponent > Int32(Int8.max) {
+            setNaN()
+            return .overflow
+        }
+        _exponent = newExponent
+        return .noError
+    }
+    fileprivate mutating func power(_ p:UInt, roundingMode:RoundingMode) -> CalculationError {
+        if isNaN {
+            return .overflow
+        }
+        var power = p
+        if power == 0 {
+            _exponent = 0
+            _length = 1
+            _isNegative = 0
+            self[0] = 1
+            _isCompact = 1
+            return .noError
+        } else if power == 1 {
+            return .noError
+        }
+
+        var temporary = Decimal(1)
+        var error:CalculationError = .noError
+
+        while power > 1 {
+            if power % 2 == 1 {
+                let previousError = error
+                error = NSDecimalMultiply(&temporary,&temporary,&self,roundingMode)
+
+                if previousError != .noError { // FIXME is this the intent?
+                    error = previousError
+                }
+
+                if error == .overflow || error == .underflow {
+                    setNaN()
+                    return error
+                }
+                power -= 1
+            }
+            if power != 0 {
+                let previousError = error
+                error = NSDecimalMultiply(&self,&self,&self,roundingMode)
+
+                if previousError != .noError { // FIXME is this the intent?
+                    error = previousError
+                }
+
+                if error == .overflow || error == .underflow {
+                    setNaN()
+                    return error
+                }
+                power /= 2
+            }
+        }
+        let previousError = error
+
+        error = NSDecimalMultiply(&self, &temporary, &self, roundingMode)
+
+        if previousError != .noError { // FIXME is this the intent?
+            error = previousError
+        }
+
+        if error == .overflow || error == .underflow {
+            setNaN()
+            return error
+        }
+
+        return error
+    }
+}
+
+fileprivate let pow10 = [
+/*^00*/ Decimal(length: 1, mantissa:( 0x0001,0,0,0,0,0,0,0)),
+/*^01*/ Decimal(length: 1, mantissa:( 0x000a,0,0,0,0,0,0,0)),
+/*^02*/ Decimal(length: 1, mantissa:( 0x0064,0,0,0,0,0,0,0)),
+/*^03*/ Decimal(length: 1, mantissa:( 0x03e8,0,0,0,0,0,0,0)),
+/*^04*/ Decimal(length: 1, mantissa:( 0x2710,0,0,0,0,0,0,0)),
+/*^05*/ Decimal(length: 2, mantissa:( 0x86a0, 0x0001,0,0,0,0,0,0)),
+/*^06*/ Decimal(length: 2, mantissa:( 0x4240, 0x000f,0,0,0,0,0,0)),
+/*^07*/ Decimal(length: 2, mantissa:( 0x9680, 0x0098,0,0,0,0,0,0)),
+/*^08*/ Decimal(length: 2, mantissa:( 0xe100, 0x05f5,0,0,0,0,0,0)),
+/*^09*/ Decimal(length: 2, mantissa:( 0xca00, 0x3b9a,0,0,0,0,0,0)),
+/*^10*/ Decimal(length: 3, mantissa:( 0xe400, 0x540b, 0x0002,0,0,0,0,0)),
+/*^11*/ Decimal(length: 3, mantissa:( 0xe800, 0x4876, 0x0017,0,0,0,0,0)),
+/*^12*/ Decimal(length: 3, mantissa:( 0x1000, 0xd4a5, 0x00e8,0,0,0,0,0)),
+/*^13*/ Decimal(length: 3, mantissa:( 0xa000, 0x4e72, 0x0918,0,0,0,0,0)),
+/*^14*/ Decimal(length: 3, mantissa:( 0x4000, 0x107a, 0x5af3,0,0,0,0,0)),
+/*^15*/ Decimal(length: 4, mantissa:( 0x8000, 0xa4c6, 0x8d7e, 0x0003,0,0,0,0)),
+/*^16*/ Decimal(length: 4, mantissa:( 0x0000, 0x6fc1, 0x86f2, 0x0023,0,0,0,0)),
+/*^17*/ Decimal(length: 4, mantissa:( 0x0000, 0x5d8a, 0x4578, 0x0163,0,0,0,0)),
+/*^18*/ Decimal(length: 4, mantissa:( 0x0000, 0xa764, 0xb6b3, 0x0de0,0,0,0,0)),
+/*^19*/ Decimal(length: 4, mantissa:( 0x0000, 0x89e8, 0x2304, 0x8ac7,0,0,0,0)),
+/*^20*/ Decimal(length: 5, mantissa:( 0x0000, 0x6310, 0x5e2d, 0x6bc7, 0x0005,0,0,0)),
+/*^21*/ Decimal(length: 5, mantissa:( 0x0000, 0xdea0, 0xadc5, 0x35c9, 0x0036,0,0,0)),
+/*^22*/ Decimal(length: 5, mantissa:( 0x0000, 0xb240, 0xc9ba, 0x19e0, 0x021e,0,0,0)),
+/*^23*/ Decimal(length: 5, mantissa:( 0x0000, 0xf680, 0xe14a, 0x02c7, 0x152d,0,0,0)),
+/*^24*/ Decimal(length: 5, mantissa:( 0x0000, 0xa100, 0xcced, 0x1bce, 0xd3c2,0,0,0)),
+/*^25*/ Decimal(length: 6, mantissa:( 0x0000, 0x4a00, 0x0148, 0x1614, 0x4595, 0x0008,0,0)),
+/*^26*/ Decimal(length: 6, mantissa:( 0x0000, 0xe400, 0x0cd2, 0xdcc8, 0xb7d2, 0x0052,0,0)),
+/*^27*/ Decimal(length: 6, mantissa:( 0x0000, 0xe800, 0x803c, 0x9fd0, 0x2e3c, 0x033b,0,0)),
+/*^28*/ Decimal(length: 6, mantissa:( 0x0000, 0x1000, 0x0261, 0x3e25, 0xce5e, 0x204f,0,0)),
+/*^29*/ Decimal(length: 7, mantissa:( 0x0000, 0xa000, 0x17ca, 0x6d72, 0x0fae, 0x431e, 0x0001,0)),
+/*^30*/ Decimal(length: 7, mantissa:( 0x0000, 0x4000, 0xedea, 0x4674, 0x9cd0, 0x9f2c, 0x000c,0)),
+/*^31*/ Decimal(length: 7, mantissa:( 0x0000, 0x8000, 0x4b26, 0xc091, 0x2022, 0x37be, 0x007e,0)),
+/*^32*/ Decimal(length: 7, mantissa:( 0x0000, 0x0000, 0xef81, 0x85ac, 0x415b, 0x2d6d, 0x04ee,0)),
+/*^33*/ Decimal(length: 7, mantissa:( 0x0000, 0x0000, 0x5b0a, 0x38c1, 0x8d93, 0xc644, 0x314d,0)),
+/*^34*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x8e64, 0x378d, 0x87c0, 0xbead, 0xed09, 0x0001)),
+/*^35*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x8fe8, 0x2b87, 0x4d82, 0x72c7, 0x4261, 0x0013)),
+/*^36*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x9f10, 0xb34b, 0x0715, 0x7bc9, 0x97ce, 0x00c0)),
+/*^37*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x36a0, 0x00f4, 0x46d9, 0xd5da, 0xee10, 0x0785)),
+/*^38*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x2240, 0x098a, 0xc47a, 0x5a86, 0x4ca8, 0x4b3b))
+/*^39 is on 9 shorts. */
+]
diff --git a/Foundation/NSDecimalNumber.swift b/Foundation/NSDecimalNumber.swift
index 759dc28..46b9b20 100644
--- a/Foundation/NSDecimalNumber.swift
+++ b/Foundation/NSDecimalNumber.swift
@@ -75,29 +75,86 @@
 
 // Receiver can raise, return a new value, or return nil to ignore the exception.
 
+fileprivate func handle(_ error: NSDecimalNumber.CalculationError, _ handler: NSDecimalNumberBehaviors) {
+    // handle the error condition, such as throwing an error for over/underflow
+}
 
 /***************	NSDecimalNumber: the class		***********/
 open class NSDecimalNumber : NSNumber {
-    
-    public convenience init(mantissa: UInt64, exponent: Int16, isNegative flag: Bool) { NSUnimplemented() }
-    public init(decimal dcm: Decimal) { NSUnimplemented() }
-    public convenience init(string numberValue: String?) { NSUnimplemented() }
-    public convenience init(string numberValue: String?, locale: AnyObject?) { NSUnimplemented() }
 
-    public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+    fileprivate let decimal: Decimal
+    public convenience init(mantissa: UInt64, exponent: Int16, isNegative: Bool) {
+        var d = Decimal()
+        d._exponent = Int32(exponent)
+        d._isNegative = isNegative ? 1 : 0
+        var man = mantissa
+        d._mantissa.0 = UInt16(man & 0xffff)
+        man >>= 4
+        d._mantissa.1 = UInt16(man & 0xffff)
+        man >>= 4
+        d._mantissa.2 = UInt16(man & 0xffff)
+        man >>= 4
+        d._mantissa.3 = UInt16(man & 0xffff)
+        d._length = 4
+        d.trimTrailingZeros()
+        // TODO more parts of the mantissa...
+        self.init(decimal: d)
+    }
+    public init(decimal dcm: Decimal) {
+        self.decimal = dcm
+        super.init()
+    }
+    public convenience init(string numberValue: String?) {
+        self.init(decimal: Decimal(string: numberValue ?? "") ?? Decimal.nan)
+    }
+    public convenience init(string numberValue: String?, locale: AnyObject?) {
+        self.init(decimal: Decimal(string: numberValue ?? "", locale: locale as? Locale) ?? Decimal.nan)
+    }
+
+    public required init?(coder: NSCoder) {
+        guard coder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        let exponent:Int32 = coder.decodeInt32(forKey: "NS.exponent")
+        let length:UInt32 = UInt32(coder.decodeInt32(forKey: "NS.length"))
+        let isNegative:UInt32 = UInt32(coder.decodeBool(forKey: "NS.negative") ? 1 : 0)
+        let isCompact:UInt32 = UInt32(coder.decodeBool(forKey: "NS.compact") ? 1 : 0)
+        // let byteOrder:UInt32 = UInt32(coder.decodeInt32(forKey: "NS.bo"))
+        guard let mantissaData: Data = coder.decodeObject(forKey: "NS.mantissa") as? Data else {
+            return nil // raise "Critical NSDecimalNumber archived data is missing"
+        }
+        guard mantissaData.count == Int(NSDecimalMaxSize * 2) else {
+            return nil  // raise "Critical NSDecimalNumber archived data is wrong size"
+        }
+        // Byte order?
+        let mantissa:(UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16) = (
+            UInt16(mantissaData[0]) << 8 & UInt16(mantissaData[1]),
+            UInt16(mantissaData[2]) << 8 & UInt16(mantissaData[3]),
+            UInt16(mantissaData[4]) << 8 & UInt16(mantissaData[5]),
+            UInt16(mantissaData[6]) << 8 & UInt16(mantissaData[7]),
+            UInt16(mantissaData[8]) << 8 & UInt16(mantissaData[9]),
+            UInt16(mantissaData[10]) << 8 & UInt16(mantissaData[11]),
+            UInt16(mantissaData[12]) << 8 & UInt16(mantissaData[13]),
+            UInt16(mantissaData[14]) << 8 & UInt16(mantissaData[15])
+        )
+        self.decimal = Decimal(_exponent: exponent, _length: length, _isNegative: isNegative, _isCompact: isCompact, _reserved: 0, _mantissa: mantissa)
+        super.init()
     }
 
     public required convenience init(floatLiteral value: Double) {
-        NSUnimplemented()
+        self.init(decimal:Decimal(value))
     }
 
     public required convenience init(booleanLiteral value: Bool) {
-        NSUnimplemented()
+        if value {
+            self.init(integerLiteral: 1)
+        } else {
+            self.init(integerLiteral: 0)
+        }
     }
 
     public required convenience init(integerLiteral value: Int) {
-        NSUnimplemented()
+        self.init(decimal:Decimal(value))
     }
     
     public required convenience init(bytes buffer: UnsafeRawPointer, objCType type: UnsafePointer<Int8>) {
@@ -105,52 +162,180 @@
     }
     
     open override func description(withLocale locale: Locale?) -> String { NSUnimplemented() }
+
+    open class var zero: NSDecimalNumber {
+        return NSDecimalNumber(integerLiteral: 0)
+    }
+    open class var one: NSDecimalNumber {
+        return NSDecimalNumber(integerLiteral: 1)
+    }
+    open class var minimum: NSDecimalNumber {
+        return NSDecimalNumber(decimal:Decimal.leastFiniteMagnitude)
+    }
+    open class var maximum: NSDecimalNumber {
+        return NSDecimalNumber(decimal:Decimal.greatestFiniteMagnitude)
+
+    }
+    open class var notANumber: NSDecimalNumber {
+        return NSDecimalNumber(decimal: Decimal.nan)
+    }
     
-    // TODO: "declarations from extensions cannot be overridden yet"
-    // Although it's not clear we actually need to redeclare this here when the extension adds it to the superclass of this class
-    // open var decimalValue: Decimal { NSUnimplemented() }
+    open func adding(_ other: NSDecimalNumber) -> NSDecimalNumber {
+        return adding(other, withBehavior: nil)
+    }
+    open func adding(_ other: NSDecimalNumber, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var left = self.decimal
+        var right = other.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalAdd(&result, &left, &right, roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
+
+    open func subtracting(_ other: NSDecimalNumber) -> NSDecimalNumber {
+        return subtracting(other, withBehavior: nil)
+    }
+    open func subtracting(_ other: NSDecimalNumber, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var left = self.decimal
+        var right = other.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalSubtract(&result, &left, &right, roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
+    open func multiplying(by other: NSDecimalNumber) -> NSDecimalNumber {
+        return multiplying(by: other, withBehavior: nil)
+    }
+    open func multiplying(by other: NSDecimalNumber, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var left = self.decimal
+        var right = other.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalMultiply(&result, &left, &right, roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
     
-    open class var zero: NSDecimalNumber { NSUnimplemented() }
-    open class var one: NSDecimalNumber { NSUnimplemented() }
-    open class var minimum: NSDecimalNumber { NSUnimplemented() }
-    open class var maximum: NSDecimalNumber { NSUnimplemented() }
-    open class var notANumber: NSDecimalNumber { NSUnimplemented() }
+    open func dividing(by other: NSDecimalNumber) -> NSDecimalNumber {
+        return dividing(by: other, withBehavior: nil)
+    }
+    open func dividing(by other: NSDecimalNumber, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var left = self.decimal
+        var right = other.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalDivide(&result, &left, &right, roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
     
-    open func adding(_ decimalNumber: NSDecimalNumber) -> NSDecimalNumber { NSUnimplemented() }
-    open func adding(_ decimalNumber: NSDecimalNumber, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
-    
-    open func subtracting(_ decimalNumber: NSDecimalNumber) -> NSDecimalNumber { NSUnimplemented() }
-    open func subtracting(_ decimalNumber: NSDecimalNumber, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
-    
-    open func multiplying(by decimalNumber: NSDecimalNumber) -> NSDecimalNumber { NSUnimplemented() }
-    open func multiplying(by decimalNumber: NSDecimalNumber, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
-    
-    open func dividing(by decimalNumber: NSDecimalNumber) -> NSDecimalNumber { NSUnimplemented() }
-    open func dividing(by decimalNumber: NSDecimalNumber, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
-    
-    open func raising(toPower power: Int) -> NSDecimalNumber { NSUnimplemented() }
-    open func raising(toPower power: Int, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
-    
-    open func multiplying(byPowerOf10 power: Int16) -> NSDecimalNumber { NSUnimplemented() }
-    open func multiplying(byPowerOf10 power: Int16, withBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
+    open func raising(toPower power: Int) -> NSDecimalNumber {
+        return raising(toPower:power, withBehavior: nil)
+    }
+    open func raising(toPower power: Int, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var input = self.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalPower(&result, &input, power, roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
+
+    open func multiplying(byPowerOf10 power: Int16) -> NSDecimalNumber {
+        return multiplying(byPowerOf10: power, withBehavior: nil)
+    }
+    open func multiplying(byPowerOf10 power: Int16, withBehavior b: NSDecimalNumberBehaviors?) -> NSDecimalNumber {
+        var result = Decimal()
+        var input = self.decimal
+        let behavior = b ?? NSDecimalNumber.defaultBehavior
+        let roundingMode = behavior.roundingMode()
+        let error = NSDecimalPower(&result, &input, Int(power), roundingMode)
+        handle(error,behavior)
+        return NSDecimalNumber(decimal: result)
+    }
     
     open func rounding(accordingToBehavior behavior: NSDecimalNumberBehaviors?) -> NSDecimalNumber { NSUnimplemented() }
     // Round to the scale of the behavior.
     
-    open override func compare(_ decimalNumber: NSNumber) -> ComparisonResult { NSUnimplemented() }
     // compare two NSDecimalNumbers
-    
-    open class var defaultBehavior: NSDecimalNumberBehaviors { NSUnimplemented() }
+    open override func compare(_ decimalNumber: NSNumber) -> ComparisonResult {
+        if let num = decimalNumber as? NSDecimalNumber {
+            return decimal.compare(to:num.decimal)
+        } else {
+            return decimal.compare(to:Decimal(decimalNumber.doubleValue))
+        }
+    }
+
+    open class var defaultBehavior: NSDecimalNumberBehaviors {
+        return NSDecimalNumberHandler.defaultBehavior
+    }
     // One behavior per thread - The default behavior is
     //   rounding mode: NSRoundPlain
     //   scale: No defined scale (full precision)
     //   ignore exactnessException
     //   raise on overflow, underflow and divide by zero.
-    
-    open override var objCType: UnsafePointer<Int8> { NSUnimplemented() }
+    static let OBJC_TYPE = "d".utf8CString
+
+    open override var objCType: UnsafePointer<Int8> {
+        return NSDecimalNumber.OBJC_TYPE.withUnsafeBufferPointer{ $0.baseAddress! }
+    }
     // return 'd' for double
     
-    open override var doubleValue: Double { NSUnimplemented() }
+    open override var int8Value: Int8 {
+        return Int8(decimal.doubleValue)
+    }
+    open override var uint8Value: UInt8 {
+        return UInt8(decimal.doubleValue)
+    }
+    open override var int16Value: Int16 {
+        return Int16(decimal.doubleValue)
+    }
+    open override var uint16Value: UInt16 {
+        return UInt16(decimal.doubleValue)
+    }
+    open override var int32Value: Int32 {
+        return Int32(decimal.doubleValue)
+    }
+    open override var uint32Value: UInt32 {
+        return UInt32(decimal.doubleValue)
+    }
+    open override var int64Value: Int64 {
+        return Int64(decimal.doubleValue)
+    }
+    open override var uint64Value: UInt64 {
+        return UInt64(decimal.doubleValue)
+    }
+    open override var floatValue: Float {
+        return Float(decimal.doubleValue)
+    }
+    open override var doubleValue: Double {
+        return decimal.doubleValue
+    }
+    open override var boolValue: Bool {
+        return !decimal.isZero
+    }
+    open override var intValue: Int {
+        return Int(decimal.doubleValue)
+    }
+    open override var uintValue: UInt {
+        return UInt(decimal.doubleValue)
+    }
+
+    open override func isEqual(_ value: Any?) -> Bool {
+        if let number = value as? NSDecimalNumber {
+            return self.decimal == number.decimal
+        } else {
+            return false
+        }
+    }
+
 }
 
 // return an approximate double value
@@ -158,33 +343,103 @@
 
 /***********	A class for defining common behaviors		*******/
 open class NSDecimalNumberHandler : NSObject, NSDecimalNumberBehaviors, NSCoding {
-    
-    public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+
+    static let defaultBehavior = NSDecimalNumberHandler()
+
+    let _roundingMode: NSDecimalNumber.RoundingMode
+    let _scale:Int16
+
+    let _raiseOnExactness: Bool
+    let _raiseOnOverflow: Bool
+    let _raiseOnUnderflow: Bool
+    let _raiseOnDivideByZero: Bool
+
+    public override init() {
+        _roundingMode = .plain
+        _scale = Int16(NSDecimalNoScale)
+
+        _raiseOnExactness = false
+        _raiseOnOverflow = true
+        _raiseOnUnderflow = true
+        _raiseOnDivideByZero = true
+    }
+    public required init?(coder: NSCoder) {
+        guard coder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        _roundingMode = NSDecimalNumber.RoundingMode(rawValue: UInt(coder.decodeInteger(forKey: "NS.roundingMode")))!
+        if coder.containsValue(forKey: "NS.scale") {
+            _scale = Int16(coder.decodeInteger(forKey: "NS.scale"))
+        } else {
+            _scale = Int16(NSDecimalNoScale)
+        }
+        _raiseOnExactness = coder.decodeBool(forKey: "NS.raise.exactness")
+        _raiseOnOverflow = coder.decodeBool(forKey: "NS.raise.overflow")
+        _raiseOnUnderflow = coder.decodeBool(forKey: "NS.raise.underflow")
+        _raiseOnDivideByZero = coder.decodeBool(forKey: "NS.raise.dividebyzero")
     }
     
-    open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+    open func encode(with coder: NSCoder) {
+        guard coder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        if _roundingMode != .plain {
+            coder.encode(Int(_roundingMode.rawValue), forKey: "NS.roundingmode")
+        }
+        if _scale != Int16(NSDecimalNoScale) {
+            coder.encode(_scale, forKey:"NS.scale")
+        }
+        if _raiseOnExactness {
+            coder.encode(_raiseOnExactness, forKey:"NS.raise.exactness")
+        }
+        if _raiseOnOverflow {
+            coder.encode(_raiseOnOverflow, forKey:"NS.raise.overflow")
+        }
+        if _raiseOnUnderflow {
+            coder.encode(_raiseOnUnderflow, forKey:"NS.raise.underflow")
+        }
+        if _raiseOnDivideByZero {
+            coder.encode(_raiseOnDivideByZero, forKey:"NS.raise.dividebyzero")
+        }
     }
     
-    open class func `default`() -> NSDecimalNumberHandler { NSUnimplemented() }
+    open class func `default`() -> NSDecimalNumberHandler {
+        return defaultBehavior
+    }
     // rounding mode: NSRoundPlain
     // scale: No defined scale (full precision)
     // ignore exactnessException (return nil)
     // raise on overflow, underflow and divide by zero.
     
-    public init(roundingMode: NSDecimalNumber.RoundingMode, scale: Int16, raiseOnExactness exact: Bool, raiseOnOverflow overflow: Bool, raiseOnUnderflow underflow: Bool, raiseOnDivideByZero divideByZero: Bool) { NSUnimplemented() }
+    public init(roundingMode: NSDecimalNumber.RoundingMode, scale: Int16, raiseOnExactness exact: Bool, raiseOnOverflow overflow: Bool, raiseOnUnderflow underflow: Bool, raiseOnDivideByZero divideByZero: Bool) {
+        _roundingMode = roundingMode
+        _scale = scale
+        _raiseOnExactness = exact
+        _raiseOnOverflow = overflow
+        _raiseOnUnderflow = underflow
+        _raiseOnDivideByZero = divideByZero
+    }
     
-    open func roundingMode() -> NSDecimalNumber.RoundingMode { NSUnimplemented() }
+    open func roundingMode() -> NSDecimalNumber.RoundingMode {
+        return _roundingMode
+    }
     
-    open func scale() -> Int16 { NSUnimplemented() }
-    // The scale could return NO_SCALE for no defined scale.
+    // The scale could return NoScale for no defined scale.
+    open func scale() -> Int16 {
+        return _scale
+    }
 }
 
 
 extension NSNumber {
     
-    public var decimalValue: Decimal { NSUnimplemented() }
+    public var decimalValue: Decimal {
+        if let d = self as? NSDecimalNumber {
+            return d.decimal
+        } else {
+            return Decimal(self.doubleValue)
+        }
+    }
 }
 
 // Could be silently inexact for float and double.
diff --git a/Foundation/NSFileHandle.swift b/Foundation/NSFileHandle.swift
old mode 100644
new mode 100755
index 8596e66..dcc3e5d
--- a/Foundation/NSFileHandle.swift
+++ b/Foundation/NSFileHandle.swift
@@ -214,11 +214,49 @@
     open class var standardError: FileHandle {
         return _stderrFileHandle
     }
-    
+
+    internal static var _nulldeviceFileHandle: FileHandle = {
+        class NullDevice: FileHandle {
+            override var availableData: Data {
+                return Data()
+            }
+
+            override func readDataToEndOfFile() -> Data {
+                return Data()
+            }
+
+            override func readData(ofLength length: Int) -> Data {
+                return Data()
+            }
+
+            override func write(_ data: Data) {}
+
+            override var offsetInFile: UInt64 {
+                return 0
+            }
+
+            override func seekToEndOfFile() -> UInt64 {
+                return 0
+            }
+
+            override func seek(toFileOffset offset: UInt64) {}
+
+            override func truncateFile(atOffset offset: UInt64) {}
+
+            override func synchronizeFile() {}
+
+            override func closeFile() {}
+
+            deinit {}
+        }
+
+        return NullDevice(fileDescriptor: -1, closeOnDealloc: false)
+    }()
+
     open class var nullDevice: FileHandle {
-        NSUnimplemented()
+        return _nulldeviceFileHandle
     }
-    
+
     public convenience init?(forReadingAtPath path: String) {
         self.init(path: path, flags: O_RDONLY, createMode: 0)
     }
diff --git a/Foundation/NSFileManager.swift b/Foundation/NSFileManager.swift
index 08b1f67..c40a1a3 100644
--- a/Foundation/NSFileManager.swift
+++ b/Foundation/NSFileManager.swift
@@ -125,7 +125,7 @@
         for attribute in attributes.keys {
             if attribute == .posixPermissions {
                 guard let number = attributes[attribute] as? NSNumber else {
-                    fatalError("Can't set file permissions to \(attributes[attribute])")
+                    fatalError("Can't set file permissions to \(attributes[attribute] as Any?)")
                 }
                 #if os(OSX) || os(iOS)
                     let modeT = number.uint16Value
diff --git a/Foundation/NSKeyedArchiver.swift b/Foundation/NSKeyedArchiver.swift
index 550b412..f9b473b 100644
--- a/Foundation/NSKeyedArchiver.swift
+++ b/Foundation/NSKeyedArchiver.swift
@@ -241,8 +241,7 @@
     }
     
     private func _validateObjectSupportsSecureCoding(_ objv : Any?) {
-        if objv != nil &&
-            self.requiresSecureCoding &&
+        if let objv = objv, self.requiresSecureCoding &&
             !NSKeyedArchiver._supportsSecureCoding(objv) {
             fatalError("Secure coding required when encoding \(objv)")
         }
@@ -271,7 +270,9 @@
             return NSKeyedArchiveNullObjectReference
         }
         
-        uid = self._objRefMap[objv as! AnyHashable]
+        let value = _SwiftValue.store(objv)!
+        
+        uid = self._objRefMap[value]
         if uid == nil {
             if conditional {
                 return nil // object has not been unconditionally encoded
@@ -279,7 +280,7 @@
             
             uid = UInt32(self._objects.count)
             
-            self._objRefMap[objv as! AnyHashable] = uid
+            self._objRefMap[value] = uid
             self._objects.insert(NSKeyedArchiveNullObjectReferenceName, at: Int(uid!))
         }
 
@@ -293,7 +294,7 @@
         if objv == nil {
             return true // always have a null reference
         } else {
-            return self._objRefMap[objv as! AnyHashable] != nil
+            return self._objRefMap[_SwiftValue.store(objv)] != nil
         }
     }
     
@@ -362,10 +363,10 @@
      */
     private func replaceObject(_ object: Any, withObject replacement: Any?) {
         if let unwrappedDelegate = self.delegate {
-            unwrappedDelegate.archiver(self, willReplace: object as! AnyHashable, with: replacement)
+            unwrappedDelegate.archiver(self, willReplace: object, with: replacement)
         }
         
-        self._replacementMap[object as! AnyHashable] = replacement
+        self._replacementMap[_SwiftValue.store(object)] = replacement
     }
    
     /**
@@ -477,9 +478,8 @@
         
         // object replaced by NSObject.replacementObjectForKeyedArchiver
         // if it is replaced with nil, it cannot be further replaced
-        if objectToEncode == nil {
-            let ns = object as? NSObject
-            objectToEncode = ns?.replacementObjectForKeyedArchiver(self)
+        if let ns = objectToEncode as? NSObject {
+            objectToEncode = ns.replacementObjectForKeyedArchiver(self)
             if objectToEncode == nil {
                 replaceObject(object!, withObject: nil)
                 return nil
@@ -511,7 +511,12 @@
 
         haveVisited = _haveVisited(objv)
         object = _replacementObject(objv)
-
+        
+        // bridge value types
+        if let bridgedObject = object as? _ObjectBridgeable {
+            object = bridgedObject._bridgeToAnyObject()
+        }
+        
         objectRef = _referenceObject(object, conditional: conditional)
         guard let unwrappedObjectRef = objectRef else {
             // we can return nil if the object is being conditionally encoded
@@ -532,12 +537,9 @@
                 _pushEncodingContext(innerEncodingContext)
                 codable.encode(with: self)
 
-                guard let ns = object as? NSObject else {
-                    fatalError("Attempt to encode non-NSObject");
-                }
-
-                let cls : AnyClass = ns.classForKeyedArchiver ?? type(of: object) as! AnyClass
-
+                let ns = object as? NSObject
+                let cls : AnyClass = ns?.classForKeyedArchiver ?? type(of: object!) as! AnyClass
+                
                 _setObjectInCurrentEncodingContext(_classReference(cls), forKey: "$class", escape: false)
                 _popEncodingContext()
                 encodedObject = innerEncodingContext.dict
diff --git a/Foundation/NSKeyedUnarchiver.swift b/Foundation/NSKeyedUnarchiver.swift
index 19a6527..b3dfc8e 100644
--- a/Foundation/NSKeyedUnarchiver.swift
+++ b/Foundation/NSKeyedUnarchiver.swift
@@ -375,7 +375,7 @@
             unwrappedDelegate.unarchiver(self, willReplace: object, with: replacement)
         }
         
-        self._replacementMap[object as! AnyHashable] = replacement
+        self._replacementMap[_SwiftValue.store(object)] = replacement
     }
     
     private func _decodingError(_ code: CocoaError.Code, withDescription description: String) -> NSError {
@@ -392,7 +392,7 @@
         }
         
         // check replacement cache
-        object = self._replacementMap[decodedObject as! AnyHashable]
+        object = self._replacementMap[_SwiftValue.store(decodedObject)]
         if object != nil {
             return object
         }
@@ -418,7 +418,7 @@
         
         if self.requiresSecureCoding && !supportsSecureCoding {
             // FIXME should this be a fatal error?
-            fatalError("Archiver \(self) requires secure coding but class \(classToConstruct) does not support it")
+            fatalError("Archiver \(self) requires secure coding but class \(classToConstruct as Optional) does not support it")
         }
         
         return supportsSecureCoding
@@ -489,9 +489,8 @@
             }
         } else {
             // reference to a non-container object
-            // FIXME remove these special cases
-            if let str = dereferencedObject as? String {
-                object = str._bridgeToObjectiveC()
+            if let bridgedObject = dereferencedObject as? _ObjectBridgeable {
+                object = bridgedObject._bridgeToAnyObject()
             } else {
                 object = dereferencedObject
             }
@@ -505,8 +504,7 @@
      */
     private func _decodeObject(forKey key: String?) throws -> Any? {
         guard let objectRef : Any? = _objectInCurrentDecodingContext(forKey: key) else {
-            throw _decodingError(CocoaError.coderValueNotFound,
-                                 withDescription: "No value found for key \(key). The data may be corrupt.")
+            throw _decodingError(CocoaError.coderValueNotFound, withDescription: "No value found for key \(key as Optional). The data may be corrupt.")
         }
         
         return try _decodeObject(objectRef!)
diff --git a/Foundation/NSLock.swift b/Foundation/NSLock.swift
index c4a9f68..e166b80 100644
--- a/Foundation/NSLock.swift
+++ b/Foundation/NSLock.swift
@@ -115,7 +115,7 @@
 
     open func lock(before limit: Date) -> Bool {
         _cond.lock()
-        while _thread == nil {
+        while _thread != nil {
             if !_cond.wait(until: limit) {
                 _cond.unlock()
                 return false
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index 724cc02..14bec84 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -290,7 +290,11 @@
         super.init()
         _CFNumberInitBool(_cfObject, value)
     }
-    
+
+    override internal init() {
+        super.init()
+    }
+
     public required convenience init(bytes buffer: UnsafeRawPointer, objCType: UnsafePointer<Int8>) {
         guard let type = _NSSimpleObjCType(UInt8(objCType.pointee)) else {
             fatalError("NSNumber.init: unsupported type encoding spec '\(String(cString: objCType))'")
diff --git a/Foundation/NSString.swift b/Foundation/NSString.swift
index 32455e9..95f5e6c 100644
--- a/Foundation/NSString.swift
+++ b/Foundation/NSString.swift
@@ -817,7 +817,7 @@
 
             return data
         }
-        return nil
+        return Data()
     }
     
     public func data(using encoding: UInt) -> Data? {
@@ -1008,8 +1008,10 @@
     open func trimmingCharacters(in set: CharacterSet) -> String {
         let len = length
         var buf = _NSStringBuffer(string: self, start: 0, end: len)
-        while !buf.isAtEnd && set.contains(UnicodeScalar(buf.currentCharacter)!) {
-            buf.advance()
+        while !buf.isAtEnd,
+            let character = UnicodeScalar(buf.currentCharacter),
+            set.contains(character) {
+                buf.advance()
         }
         
         let startOfNonTrimmedRange = buf.location // This points at the first char not in the set
@@ -1018,8 +1020,10 @@
             return ""
         } else if startOfNonTrimmedRange < len - 1 {
             buf.location = len - 1
-            while set.contains(UnicodeScalar(buf.currentCharacter)!) && buf.location >= startOfNonTrimmedRange {
-                buf.rewind()
+            while let character = UnicodeScalar(buf.currentCharacter),
+                set.contains(character),
+                buf.location >= startOfNonTrimmedRange {
+                    buf.rewind()
             }
             let endOfNonTrimmedRange = buf.location
             return substring(with: NSMakeRange(startOfNonTrimmedRange, endOfNonTrimmedRange + 1 - startOfNonTrimmedRange))
diff --git a/Foundation/NSURLCredential.swift b/Foundation/NSURLCredential.swift
index 300126a..32cd075 100644
--- a/Foundation/NSURLCredential.swift
+++ b/Foundation/NSURLCredential.swift
@@ -65,11 +65,32 @@
      */
     
     public required init?(coder aDecoder: NSCoder) {
-        NSUnimplemented()
+        guard aDecoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        func bridgeString(_ value: NSString) -> String? {
+            return String._unconditionallyBridgeFromObjectiveC(value)
+        }
+        
+        let encodedUser = aDecoder.decodeObject(forKey: "NS._user") as! NSString
+        self._user = bridgeString(encodedUser)!
+        
+        let encodedPassword = aDecoder.decodeObject(forKey: "NS._password") as! NSString
+        self._password = bridgeString(encodedPassword)!
+        
+        let encodedPersistence = aDecoder.decodeObject(forKey: "NS._persistence") as! NSNumber
+        self._persistence = Persistence(rawValue: encodedPersistence.uintValue)!
     }
     
     open func encode(with aCoder: NSCoder) {
-        NSUnimplemented()
+        guard aCoder.allowsKeyedCoding else {
+            preconditionFailure("Unkeyed coding is unsupported.")
+        }
+        
+        aCoder.encode(self._user._bridgeToObjectiveC(), forKey: "NS._user")
+        aCoder.encode(self._password._bridgeToObjectiveC(), forKey: "NS._password")
+        aCoder.encode(self._persistence.rawValue._bridgeToObjectiveC(), forKey: "NS._persistence")
     }
     
     static public var supportsSecureCoding: Bool {
@@ -84,6 +105,17 @@
         return self 
     }
     
+    open override func isEqual(_ object: Any?) -> Bool {
+        if let other = object as? URLCredential {
+            return other === self
+                || (other._user == self._user
+                    && other._password == self._password
+                    && other._persistence == self._persistence)
+        }
+        
+        return false
+    }
+    
     /*!
         @method persistence
         @abstract Determine whether this credential is or should be stored persistently
diff --git a/Foundation/NSURLSession/HTTPMessage.swift b/Foundation/NSURLSession/HTTPMessage.swift
index 4f41eef..6598d06 100644
--- a/Foundation/NSURLSession/HTTPMessage.swift
+++ b/Foundation/NSURLSession/HTTPMessage.swift
@@ -143,7 +143,12 @@
     var headersAsDictionary: [String: String] {
         var result: [String: String] = [:]
         headers.forEach {
-            result[$0.name] = $0.value
+            if result[$0.name] == nil {
+                result[$0.name] = $0.value
+            }
+            else {
+                result[$0.name]! += (", " + $0.value)
+            }
         }
         return result
     }
@@ -287,8 +292,13 @@
         var value: String?
         let line = headView[headView.index(after: nameRange.upperBound)..<headView.endIndex]
         if !line.isEmpty {
-            guard let v = line.trimSPHTPrefix else { return nil }
-            value = String(v)
+            if line.hasSPHTPrefix && line.count == 1 {
+                // to handle empty headers i.e header without value
+                value = String("")
+            } else {
+                guard let v = line.trimSPHTPrefix else { return nil }
+                value = String(v)
+            }
         }
         do {
             var t = tail
diff --git a/Foundation/NSURLSession/NSURLSessionTask.swift b/Foundation/NSURLSession/NSURLSessionTask.swift
index f8b9569..27ad59f 100644
--- a/Foundation/NSURLSession/NSURLSessionTask.swift
+++ b/Foundation/NSURLSession/NSURLSessionTask.swift
@@ -88,7 +88,7 @@
         originalRequest = nil
         body = .none
         workQueue = DispatchQueue(label: "URLSessionTask.notused.0")
-        taskAttributesIsolation = DispatchQueue(label: "URLSessionTask.notused.1")
+        taskAttributesIsolation = DispatchQueue(label: "URLSessionTask.notused.1", attributes: DispatchQueue.Attributes.concurrent)
         let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
         _ = FileManager.default.createFile(atPath: fileName, contents: nil)
         self.tempFileURL = URL(fileURLWithPath: fileName)
@@ -145,7 +145,7 @@
             return r
         }
         //TODO: dispatch_barrier_async
-        set { taskAttributesIsolation.async { self._currentRequest = newValue } }
+        set { taskAttributesIsolation.async(flags: .barrier) { self._currentRequest = newValue } }
     }
     fileprivate var _currentRequest: URLRequest? = nil
     /*@NSCopying*/ open fileprivate(set) var response: URLResponse? {
@@ -154,7 +154,7 @@
             taskAttributesIsolation.sync { r = self._response }
             return r
         }
-        set { taskAttributesIsolation.async { self._response = newValue } }
+        set { taskAttributesIsolation.async(flags: .barrier) { self._response = newValue } }
     }
     fileprivate var _response: URLResponse? = nil
     
@@ -170,7 +170,7 @@
             taskAttributesIsolation.sync { r = self._countOfBytesReceived }
             return r
         }
-        set { taskAttributesIsolation.async { self._countOfBytesReceived = newValue } }
+        set { taskAttributesIsolation.async(flags: .barrier) { self._countOfBytesReceived = newValue } }
     }
     fileprivate var _countOfBytesReceived: Int64 = 0
     
@@ -181,7 +181,7 @@
             taskAttributesIsolation.sync { r = self._countOfBytesSent }
             return r
         }
-        set { taskAttributesIsolation.async { self._countOfBytesSent = newValue } }
+        set { taskAttributesIsolation.async(flags: .barrier) { self._countOfBytesSent = newValue } }
     }
 
     fileprivate var _countOfBytesSent: Int64 = 0
@@ -213,7 +213,7 @@
             taskAttributesIsolation.sync { r = self._state }
             return r
         }
-        set { taskAttributesIsolation.async { self._state = newValue } }
+        set { taskAttributesIsolation.async(flags: .barrier) { self._state = newValue } }
     }
     fileprivate var _state: URLSessionTask.State = .suspended
     
@@ -298,7 +298,7 @@
             return r
         }
         set {
-            taskAttributesIsolation.async { self._priority = newValue }
+            taskAttributesIsolation.async(flags: .barrier) { self._priority = newValue }
         }
     }
     fileprivate var _priority: Float = URLSessionTaskPriorityDefault
@@ -791,7 +791,7 @@
         // to the delegate. But in case of redirects etc. we might send another
         // request.
         guard case .transferInProgress(let ts) = internalState else { fatalError("Transfer completed, but it wasn't in progress.") }
-        guard let request = currentRequest else { fatalError("Transfer completed, but there's no currect request.") }
+        guard let request = currentRequest else { fatalError("Transfer completed, but there's no current request.") }
         guard errorCode == nil else {
             internalState = .transferFailed
             failWith(errorCode: errorCode!, request: request)
diff --git a/Foundation/Notification.swift b/Foundation/Notification.swift
index 46cbc64..d929dbe 100644
--- a/Foundation/Notification.swift
+++ b/Foundation/Notification.swift
@@ -40,9 +40,12 @@
     public var hashValue: Int {
         return name.rawValue.hash
     }
-    
+
     public var description: String {
-        return "name = \(name.rawValue),  object = \(object), userInfo = \(userInfo)"
+        var description = "name = \(name.rawValue)"
+        if let obj = object { description += ", object = \(obj)" }
+        if let info = userInfo { description += ", userInfo = \(info)" }
+        return description
     }
     
     public var debugDescription: String {
@@ -73,7 +76,17 @@
 
 extension Notification : CustomReflectable {
     public var customMirror: Mirror {
-        NSUnimplemented()
+        var children: [(label: String?, value: Any)] = [(label: "name", self.name.rawValue)]
+
+        if let object = self.object {
+            children.append((label: "object", object))
+        }
+
+        if let info = self.userInfo {
+            children.append((label: "userInfo", info))
+        }
+
+        return Mirror(self, children: children, displayStyle: .class)
     }
 }
 
diff --git a/TestFoundation/TestNSCharacterSet.swift b/TestFoundation/TestNSCharacterSet.swift
index 71ff177..7bd9d62 100644
--- a/TestFoundation/TestNSCharacterSet.swift
+++ b/TestFoundation/TestNSCharacterSet.swift
@@ -28,7 +28,7 @@
             ("testRanges", testRanges),
             ("testInsertAndRemove", testInsertAndRemove),
             ("testBasics", testBasics),
-            
+            ("testClosedRanges_SR_2988", testClosedRanges_SR_2988),
             ("test_Predefines", test_Predefines),
             ("test_Range", test_Range),
             ("test_String", test_String),
@@ -223,6 +223,18 @@
         }
     }
     
+    func testClosedRanges_SR_2988() {
+        // "CharacterSet.insert(charactersIn: ClosedRange) crashes on a closed ClosedRange<UnicodeScalar> containing U+D7FF"
+        let problematicChar = UnicodeScalar(0xD7FF)!
+        let range = capitalA...problematicChar
+        var characters = CharacterSet(charactersIn: range) // this should not crash
+        XCTAssertTrue(characters.contains(problematicChar))
+        characters.remove(charactersIn: range) // this should not crash
+        XCTAssertTrue(!characters.contains(problematicChar))
+        characters.insert(charactersIn: range) // this should not crash
+        XCTAssertTrue(characters.contains(problematicChar))
+    }
+    
     func test_Bitmap() {
         
     }
diff --git a/TestFoundation/TestNSData.swift b/TestFoundation/TestNSData.swift
index 9705c15..44daab7 100644
--- a/TestFoundation/TestNSData.swift
+++ b/TestFoundation/TestNSData.swift
@@ -89,6 +89,7 @@
             ("test_replaceBytes", test_replaceBytes),
             ("test_initDataWithCapacity", test_initDataWithCapacity),
             ("test_initDataWithCount", test_initDataWithCount),
+            ("test_emptyStringToData", test_emptyStringToData),
         ]
     }
     
@@ -438,6 +439,11 @@
             return
         }
     }
+
+    func test_emptyStringToData() {
+        let data = "".data(using: .utf8)!
+        XCTAssertEqual(0, data.count, "data from empty string is empty")
+    }
 }
 
 // Tests from Swift SDK Overlay
diff --git a/TestFoundation/TestNSDecimal.swift b/TestFoundation/TestNSDecimal.swift
new file mode 100644
index 0000000..ffddd40
--- /dev/null
+++ b/TestFoundation/TestNSDecimal.swift
@@ -0,0 +1,608 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 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 TestNSDecimal: XCTestCase {
+
+    static var allTests : [(String, (TestNSDecimal) -> () throws -> Void)] {
+        return [
+            ("test_AdditionWithNormalization", test_AdditionWithNormalization),
+            ("test_BasicConstruction", test_BasicConstruction),
+            ("test_Constants", test_Constants),
+            ("test_Description", test_Description),
+            ("test_ExplicitConstruction", test_ExplicitConstruction),
+            ("test_Maths", test_Maths),
+            ("test_Misc", test_Misc),
+            ("test_MultiplicationOverflow", test_MultiplicationOverflow),
+            ("test_NaNInput", test_NaNInput),
+            ("test_NegativeAndZeroMultiplication", test_NegativeAndZeroMultiplication),
+            ("test_Normalise", test_Normalise),
+            ("test_NSDecimal", test_NSDecimal),
+            ("test_PositivePowers", test_PositivePowers),
+            ("test_RepeatingDivision", test_RepeatingDivision),
+            ("test_Round", test_Round),
+            ("test_SimpleMultiplication", test_SimpleMultiplication),
+            ("test_SmallerNumbers", test_SmallerNumbers),
+            ("test_ZeroPower", test_ZeroPower),
+        ]
+    }
+
+    func test_AdditionWithNormalization() {
+
+        let biggie = Decimal(65536)
+        let smallee = Decimal(65536)
+        let answer = biggie/smallee
+        XCTAssertEqual(Decimal(1),answer)
+
+        var one = Decimal(1)
+        var addend = Decimal(1)
+        var expected = Decimal()
+        var result = Decimal()
+
+        expected._isNegative = 0;
+        expected._isCompact = 0;
+
+        // 2 digits -- certain to work
+        addend._exponent = -1;
+        XCTAssertEqual(.noError, NSDecimalAdd(&result, &one, &addend, .plain), "1 + 0.1")
+        expected._exponent = -1;
+        expected._length = 1;
+        expected._mantissa.0 = 11;
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&expected, &result), "1.1 == 1 + 0.1")
+
+        // 38 digits -- guaranteed by NSDecimal to work
+        addend._exponent = -37;
+        XCTAssertEqual(.noError, NSDecimalAdd(&result, &one, &addend, .plain), "1 + 1e-37")
+        expected._exponent = -37;
+        expected._length = 8;
+        expected._mantissa.0 = 0x0001;
+        expected._mantissa.1 = 0x0000;
+        expected._mantissa.2 = 0x36a0;
+        expected._mantissa.3 = 0x00f4;
+        expected._mantissa.4 = 0x46d9;
+        expected._mantissa.5 = 0xd5da;
+        expected._mantissa.6 = 0xee10;
+        expected._mantissa.7 = 0x0785;
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&expected, &result), "1 + 1e-37")
+
+        // 39 digits -- not guaranteed to work but it happens to, so we make the test work either way
+        addend._exponent = -38;
+        let error = NSDecimalAdd(&result, &one, &addend, .plain)
+        XCTAssertTrue(error == .noError || error == .lossOfPrecision, "1 + 1e-38")
+        if error == .noError {
+            expected._exponent = -38;
+            expected._length = 8;
+            expected._mantissa.0 = 0x0001;
+            expected._mantissa.1 = 0x0000;
+            expected._mantissa.2 = 0x2240;
+            expected._mantissa.3 = 0x098a;
+            expected._mantissa.4 = 0xc47a;
+            expected._mantissa.5 = 0x5a86;
+            expected._mantissa.6 = 0x4ca8;
+            expected._mantissa.7 = 0x4b3b;
+            XCTAssertEqual(.orderedSame, NSDecimalCompare(&expected, &result), "1 + 1e-38")
+        } else {
+            XCTAssertEqual(.orderedSame, NSDecimalCompare(&one, &result), "1 + 1e-38")
+        }
+
+        // 40 digits -- doesn't work; need to make sure it's rounding for us
+        addend._exponent = -39;
+        XCTAssertEqual(.lossOfPrecision, NSDecimalAdd(&result, &one, &addend, .plain), "1 + 1e-39")
+        XCTAssertEqual("1", result.description)
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&one, &result), "1 + 1e-39")
+    }
+
+    func test_BasicConstruction() {
+        let zero = Decimal()
+        XCTAssertEqual(20, MemoryLayout<Decimal>.size)
+        XCTAssertEqual(0, zero._exponent)
+        XCTAssertEqual(0, zero._length)
+        XCTAssertEqual(0, zero._isNegative)
+        XCTAssertEqual(0, zero._isCompact)
+        XCTAssertEqual(0, zero._reserved)
+        let (m0, m1, m2, m3, m4, m5, m6, m7) = zero._mantissa
+        XCTAssertEqual(0, m0)
+        XCTAssertEqual(0, m1)
+        XCTAssertEqual(0, m2)
+        XCTAssertEqual(0, m3)
+        XCTAssertEqual(0, m4)
+        XCTAssertEqual(0, m5)
+        XCTAssertEqual(0, m6)
+        XCTAssertEqual(0, m7)
+        XCTAssertEqual(8, NSDecimalMaxSize)
+        XCTAssertEqual(32767, NSDecimalNoScale)
+        XCTAssertFalse(zero.isNormal)
+        XCTAssertTrue(zero.isFinite)
+        XCTAssertTrue(zero.isZero)
+        XCTAssertFalse(zero.isSubnormal)
+        XCTAssertFalse(zero.isInfinite)
+        XCTAssertFalse(zero.isNaN)
+        XCTAssertFalse(zero.isSignaling)
+    }
+    func test_Constants() {
+        XCTAssertEqual(8, NSDecimalMaxSize)
+        XCTAssertEqual(32767, NSDecimalNoScale)
+        let smallest = Decimal(_exponent: 127, _length: 8, _isNegative: 1, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
+        XCTAssertEqual(smallest, Decimal.leastFiniteMagnitude)
+        let biggest = Decimal(_exponent: 127, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
+        XCTAssertEqual(biggest, Decimal.greatestFiniteMagnitude)
+        let leastNormal = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
+        XCTAssertEqual(leastNormal, Decimal.leastNormalMagnitude)
+        let leastNonzero = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
+        XCTAssertEqual(leastNonzero, Decimal.leastNonzeroMagnitude)
+        let pi = Decimal(_exponent: -38, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58))
+        XCTAssertEqual(pi, Decimal.pi)
+        XCTAssertEqual(10, Decimal.radix)
+        XCTAssertTrue(Decimal().isCanonical)
+        XCTAssertFalse(Decimal().isSignalingNaN)
+        XCTAssertFalse(Decimal.nan.isSignalingNaN)
+        XCTAssertTrue(Decimal.nan.isNaN)
+        XCTAssertEqual(.quietNaN, Decimal.nan.floatingPointClass)
+        XCTAssertEqual(.positiveZero, Decimal().floatingPointClass)
+        XCTAssertEqual(.negativeNormal, smallest.floatingPointClass)
+        XCTAssertEqual(.positiveNormal, biggest.floatingPointClass)
+        XCTAssertFalse(Double.nan.isFinite)
+        XCTAssertFalse(Double.nan.isInfinite)
+    }
+
+    func test_Description() {
+        XCTAssertEqual("0", Decimal().description)
+        XCTAssertEqual("0", Decimal(0).description)
+        XCTAssertEqual("10", Decimal(_exponent: 1, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0)).description)
+        XCTAssertEqual("10", Decimal(10).description)
+        XCTAssertEqual("123.458", Decimal(_exponent: -3, _length: 2, _isNegative: 0, _isCompact:1, _reserved: 0, _mantissa: (57922, 1, 0, 0, 0, 0, 0, 0)).description)
+        XCTAssertEqual("123.458", Decimal(123.458).description)
+        XCTAssertEqual("123", Decimal(UInt8(123)).description)
+        XCTAssertEqual("45", Decimal(Int8(45)).description)
+        XCTAssertEqual("3.14159265358979323846264338327950288419", Decimal.pi.description)
+        XCTAssertEqual("-30000000000", Decimal(sign: .minus, exponent: 10, significand: Decimal(3)).description)
+        XCTAssertEqual("300000", Decimal(sign: .plus, exponent: 5, significand: Decimal(3)).description)
+        XCTAssertEqual("5", Decimal(signOf: Decimal(3), magnitudeOf: Decimal(5)).description)
+        XCTAssertEqual("-5", Decimal(signOf: Decimal(-3), magnitudeOf: Decimal(5)).description)
+        XCTAssertEqual("5", Decimal(signOf: Decimal(3), magnitudeOf: Decimal(-5)).description)
+        XCTAssertEqual("-5", Decimal(signOf: Decimal(-3), magnitudeOf: Decimal(-5)).description)
+    }
+
+    func test_ExplicitConstruction() {
+        var explicit = Decimal(
+            _exponent: 0x17f,
+            _length: 0xff,
+            _isNegative: 3,
+            _isCompact: 4,
+            _reserved: UInt32(1<<18 + 1<<17 + 1),
+            _mantissa: (6, 7, 8, 9, 10, 11, 12, 13)
+        )
+        XCTAssertEqual(0x7f, explicit._exponent)
+        XCTAssertEqual(0x7f, explicit.exponent)
+        XCTAssertEqual(0x0f, explicit._length)
+        XCTAssertEqual(1, explicit._isNegative)
+        XCTAssertEqual(FloatingPointSign.minus, explicit.sign)
+        XCTAssertTrue(explicit.isSignMinus)
+        XCTAssertEqual(0, explicit._isCompact)
+        XCTAssertEqual(UInt32(1<<17 + 1), explicit._reserved)
+        let (m0, m1, m2, m3, m4, m5, m6, m7) = explicit._mantissa
+        XCTAssertEqual(6, m0)
+        XCTAssertEqual(7, m1)
+        XCTAssertEqual(8, m2)
+        XCTAssertEqual(9, m3)
+        XCTAssertEqual(10, m4)
+        XCTAssertEqual(11, m5)
+        XCTAssertEqual(12, m6)
+        XCTAssertEqual(13, m7)
+        explicit._isCompact = 5
+        explicit._isNegative = 6
+        XCTAssertEqual(0, explicit._isNegative)
+        XCTAssertEqual(1, explicit._isCompact)
+        XCTAssertEqual(FloatingPointSign.plus, explicit.sign)
+        XCTAssertFalse(explicit.isSignMinus)
+        XCTAssertTrue(explicit.isNormal)
+
+        let significand = explicit.significand
+        XCTAssertEqual(0, significand._exponent)
+        XCTAssertEqual(0, significand.exponent)
+        XCTAssertEqual(0x0f, significand._length)
+        XCTAssertEqual(0, significand._isNegative)
+        XCTAssertEqual(1, significand._isCompact)
+        XCTAssertEqual(0, significand._reserved)
+        let (sm0, sm1, sm2, sm3, sm4, sm5, sm6, sm7) = significand._mantissa
+        XCTAssertEqual(6, sm0)
+        XCTAssertEqual(7, sm1)
+        XCTAssertEqual(8, sm2)
+        XCTAssertEqual(9, sm3)
+        XCTAssertEqual(10, sm4)
+        XCTAssertEqual(11, sm5)
+        XCTAssertEqual(12, sm6)
+        XCTAssertEqual(13, sm7)
+
+        let ulp = explicit.ulp
+        XCTAssertEqual(0x7f, ulp.exponent)
+        XCTAssertEqual(8, ulp._length)
+        XCTAssertEqual(0, ulp._isNegative)
+        XCTAssertEqual(1, ulp._isCompact)
+        XCTAssertEqual(0, ulp._reserved)
+        XCTAssertEqual(1, ulp._mantissa.0)
+        XCTAssertEqual(0, ulp._mantissa.1)
+        XCTAssertEqual(0, ulp._mantissa.2)
+        XCTAssertEqual(0, ulp._mantissa.3)
+        XCTAssertEqual(0, ulp._mantissa.4)
+        XCTAssertEqual(0, ulp._mantissa.5)
+        XCTAssertEqual(0, ulp._mantissa.6)
+        XCTAssertEqual(0, ulp._mantissa.7)
+    }
+
+    func test_Maths() {
+        for i in -2...10 {
+            for j in 0...5 {
+                XCTAssertEqual(Decimal(i*j), Decimal(i) * Decimal(j), "\(Decimal(i*j)) == \(i) * \(j)")
+                XCTAssertEqual(Decimal(i+j), Decimal(i) + Decimal(j), "\(Decimal(i+j)) == \(i)+\(j)")
+                XCTAssertEqual(Decimal(i-j), Decimal(i) - Decimal(j), "\(Decimal(i-j)) == \(i)-\(j)")
+                if j != 0 {
+                    let approximation = Decimal(Double(i)/Double(j))
+                    let answer = Decimal(i) / Decimal(j)
+                    let answerDescription = answer.description
+                    let approximationDescription = approximation.description
+                    var failed: Bool = false
+                    var count = 0
+                    let SIG_FIG = 14
+                    for (a, b) in zip(answerDescription.characters, approximationDescription.characters) {
+                        if a != b {
+                            failed = true
+                            break
+                        }
+                        if count == 0 && (a == "-" || a == "0" || a == ".") {
+                            continue // don't count these as significant figures
+                        }
+                        if count >= SIG_FIG {
+                            break
+                        }
+                        count += 1
+                    }
+                    XCTAssertFalse(failed, "\(Decimal(i/j)) == \(i)/\(j)")
+                }
+            }
+        }
+        XCTAssertEqual(Decimal(186243*15673), Decimal(186243) * Decimal(15673))
+    }
+
+    func test_Misc() {
+        XCTAssertEqual(.minus, Decimal(-5.2).sign)
+        XCTAssertEqual(.plus, Decimal(5.2).sign)
+        var d = Decimal(5.2)
+        XCTAssertEqual(.plus, d.sign)
+        d.negate()
+        XCTAssertEqual(.minus, d.sign)
+        d.negate()
+        XCTAssertEqual(.plus, d.sign)
+        XCTAssertTrue(Decimal(3.5).isEqual(to: Decimal(3.5)))
+        XCTAssertTrue(Decimal.nan.isEqual(to: Decimal.nan))
+        XCTAssertTrue(Decimal(1.28).isLess(than: Decimal(2.24)))
+        XCTAssertFalse(Decimal(2.28).isLess(than: Decimal(2.24)))
+        XCTAssertTrue(Decimal(1.28).isTotallyOrdered(belowOrEqualTo: Decimal(2.24)))
+        XCTAssertFalse(Decimal(2.28).isTotallyOrdered(belowOrEqualTo: Decimal(2.24)))
+        XCTAssertTrue(Decimal(1.2).isTotallyOrdered(belowOrEqualTo: Decimal(1.2)))
+        XCTAssertTrue(Decimal.nan.isEqual(to: Decimal.nan))
+        XCTAssertTrue(Decimal.nan.isLess(than: Decimal(0)))
+        XCTAssertFalse(Decimal.nan.isLess(than: Decimal.nan))
+        XCTAssertTrue(Decimal.nan.isLessThanOrEqualTo(Decimal(0)))
+        XCTAssertTrue(Decimal.nan.isLessThanOrEqualTo(Decimal.nan))
+        XCTAssertFalse(Decimal.nan.isTotallyOrdered(belowOrEqualTo: Decimal.nan))
+        XCTAssertFalse(Decimal.nan.isTotallyOrdered(belowOrEqualTo: Decimal(2.3)))
+        XCTAssertTrue(Decimal(2) < Decimal(3))
+        XCTAssertTrue(Decimal(3) > Decimal(2))
+        XCTAssertEqual(3275573729074, Decimal(1234).hashValue)
+        XCTAssertEqual(Decimal(-9), Decimal(1) - Decimal(10))
+        XCTAssertEqual(Decimal(3), Decimal(2).nextUp)
+        XCTAssertEqual(Decimal(2), Decimal(3).nextDown)
+        XCTAssertEqual(Decimal(-476), Decimal(1024).distance(to: Decimal(1500)))
+        XCTAssertEqual(Decimal(68040), Decimal(386).advanced(by: Decimal(67654)))
+        XCTAssertEqual(Decimal(1.234), abs(Decimal(1.234)))
+        XCTAssertEqual(Decimal(1.234), abs(Decimal(-1.234)))
+        var a = Decimal(1234)
+        XCTAssertEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, 1, .plain))
+        XCTAssertEqual(Decimal(12340), a)
+        a = Decimal(1234)
+        XCTAssertEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, 2, .plain))
+        XCTAssertEqual(Decimal(123400), a)
+        XCTAssertEqual(.overflow, NSDecimalMultiplyByPowerOf10(&a, &a, 128, .plain))
+        XCTAssertTrue(a.isNaN)
+        a = Decimal(1234)
+        XCTAssertEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, -2, .plain))
+        XCTAssertEqual(Decimal(12.34), a)
+        XCTAssertEqual(.underflow, NSDecimalMultiplyByPowerOf10(&a, &a, -128, .plain))
+        XCTAssertTrue(a.isNaN)
+        a = Decimal(1234)
+        XCTAssertEqual(.noError, NSDecimalPower(&a, &a, 0, .plain))
+        XCTAssertEqual(Decimal(1), a)
+        a = Decimal(8)
+        XCTAssertEqual(.noError, NSDecimalPower(&a, &a, 2, .plain))
+        XCTAssertEqual(Decimal(64), a)
+        a = Decimal(-2)
+        XCTAssertEqual(.noError, NSDecimalPower(&a, &a, 3, .plain))
+        XCTAssertEqual(Decimal(-8), a)
+        for i in -2...10 {
+            for j in 0...5 {
+                var actual = Decimal(i)
+                XCTAssertEqual(.noError, NSDecimalPower(&actual, &actual, j, .plain))
+                let expected = Decimal(pow(Double(i), Double(j)))
+                XCTAssertEqual(expected, actual, "\(actual) == \(i)^\(j)")
+            }
+        }
+    }
+
+    func test_MultiplicationOverflow() {
+        var multiplicand = Decimal(_exponent: 0, _length: 8, _isNegative: 0, _isCompact: 0, _reserved: 0, _mantissa: ( 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff ))
+
+        var result = Decimal()
+        var multiplier = Decimal(1)
+
+        multiplier._mantissa.0 = 2
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &multiplicand, &multiplier, .plain), "2 * max mantissa")
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &multiplier, &multiplicand, .plain), "max mantissa * 2")
+
+        multiplier._exponent = 0x7f
+        XCTAssertEqual(.overflow, NSDecimalMultiply(&result, &multiplicand, &multiplier, .plain), "2e127 * max mantissa")
+        XCTAssertEqual(.overflow, NSDecimalMultiply(&result, &multiplier, &multiplicand, .plain), "max mantissa * 2e127")
+    }
+
+    func test_NaNInput() {
+        var NaN = Decimal.nan
+        var one = Decimal(1)
+        var result = Decimal()
+
+        XCTAssertNotEqual(.noError, NSDecimalAdd(&result, &NaN, &one, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN + 1")
+        XCTAssertNotEqual(.noError, NSDecimalAdd(&result, &one, &NaN, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "1 + NaN")
+
+        XCTAssertNotEqual(.noError, NSDecimalSubtract(&result, &NaN, &one, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN - 1")
+        XCTAssertNotEqual(.noError, NSDecimalSubtract(&result, &one, &NaN, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "1 - NaN")
+
+        XCTAssertNotEqual(.noError, NSDecimalMultiply(&result, &NaN, &one, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN * 1")
+        XCTAssertNotEqual(.noError, NSDecimalMultiply(&result, &one, &NaN, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "1 * NaN")
+
+        XCTAssertNotEqual(.noError, NSDecimalDivide(&result, &NaN, &one, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN / 1")
+        XCTAssertNotEqual(.noError, NSDecimalDivide(&result, &one, &NaN, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "1 / NaN")
+
+        XCTAssertNotEqual(.noError, NSDecimalPower(&result, &NaN, 0, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN ^ 0")
+        XCTAssertNotEqual(.noError, NSDecimalPower(&result, &NaN, 4, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN ^ 4")
+        XCTAssertNotEqual(.noError, NSDecimalPower(&result, &NaN, 5, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN ^ 5")
+
+        XCTAssertNotEqual(.noError, NSDecimalMultiplyByPowerOf10(&result, &NaN, 0, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN e0")
+        XCTAssertNotEqual(.noError, NSDecimalMultiplyByPowerOf10(&result, &NaN, 4, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN e4")
+        XCTAssertNotEqual(.noError, NSDecimalMultiplyByPowerOf10(&result, &NaN, 5, .plain))
+        XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN e5")
+    }
+
+    func test_NegativeAndZeroMultiplication() {
+        var one = Decimal(1)
+        var zero = Decimal(0)
+        var negativeOne = Decimal(-1)
+
+        var result = Decimal()
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &one, &one, .plain), "1 * 1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&one, &result), "1 * 1")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &one, &negativeOne, .plain), "1 * -1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&negativeOne, &result), "1 * -1")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &negativeOne, &one, .plain), "-1 * 1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&negativeOne, &result), "-1 * 1")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &negativeOne, &negativeOne, .plain), "-1 * -1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&one, &result), "-1 * -1")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &one, &zero, .plain), "1 * 0")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&zero, &result), "1 * 0")
+        XCTAssertEqual(0, result._isNegative, "1 * 0")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &zero, &one, .plain), "0 * 1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&zero, &result), "0 * 1")
+        XCTAssertEqual(0, result._isNegative, "0 * 1")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &negativeOne, &zero, .plain), "-1 * 0")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&zero, &result), "-1 * 0")
+        XCTAssertEqual(0, result._isNegative, "-1 * 0")
+
+        XCTAssertEqual(.noError, NSDecimalMultiply(&result, &zero, &negativeOne, .plain), "0 * -1")
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&zero, &result), "0 * -1")
+        XCTAssertEqual(0, result._isNegative, "0 * -1")
+    }
+
+    func test_Normalise() {
+        var one = Decimal(1)
+        var ten = Decimal(-10)
+        XCTAssertEqual(.noError, NSDecimalNormalize(&one, &ten, .plain))
+        XCTAssertEqual(Decimal(1), one)
+        XCTAssertEqual(Decimal(-10), ten)
+        XCTAssertEqual(1, one._length)
+        XCTAssertEqual(1, ten._length)
+        one = Decimal(1)
+        ten = Decimal(10)
+        XCTAssertEqual(.noError, NSDecimalNormalize(&one, &ten, .plain))
+        XCTAssertEqual(Decimal(1), one)
+        XCTAssertEqual(Decimal(10), ten)
+        XCTAssertEqual(1, one._length)
+        XCTAssertEqual(1, ten._length)
+    }
+
+    func test_NSDecimal() {
+        var nan = Decimal.nan
+        XCTAssertTrue(NSDecimalIsNotANumber(&nan))
+        var zero = Decimal()
+        XCTAssertFalse(NSDecimalIsNotANumber(&zero))
+        var three = Decimal(3)
+        var guess = Decimal()
+        NSDecimalCopy(&guess, &three)
+        XCTAssertEqual(three, guess)
+
+        var f = Decimal(_exponent: 0, _length: 2, _isNegative: 0, _isCompact: 0, _reserved: 0, _mantissa: (0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
+        let before = f.description
+        XCTAssertEqual(0, f._isCompact)
+        NSDecimalCompact(&f)
+        XCTAssertEqual(1, f._isCompact)
+        let after = f.description
+        XCTAssertEqual(before, after)
+    }
+
+    func test_PositivePowers() {
+        let six = NSDecimalNumber(integerLiteral: 6)
+
+        XCTAssertEqual(6, six.raising(toPower:1).intValue)
+        XCTAssertEqual(36, six.raising(toPower:2).intValue)
+        XCTAssertEqual(216, six.raising(toPower:3).intValue)
+        XCTAssertEqual(1296, six.raising(toPower:4).intValue)
+        XCTAssertEqual(7776, six.raising(toPower:5).intValue)
+        XCTAssertEqual(46656, six.raising(toPower:6).intValue)
+        XCTAssertEqual(279936, six.raising(toPower:7).intValue)
+        XCTAssertEqual(1679616, six.raising(toPower:8).intValue)
+        XCTAssertEqual(10077696, six.raising(toPower:9).intValue)
+
+        let negativeSix = NSDecimalNumber(integerLiteral: -6)
+
+        XCTAssertEqual(-6, negativeSix.raising(toPower:1).intValue)
+        XCTAssertEqual(36, negativeSix.raising(toPower:2).intValue)
+        XCTAssertEqual(-216, negativeSix.raising(toPower:3).intValue)
+        XCTAssertEqual(1296, negativeSix.raising(toPower:4).intValue)
+        XCTAssertEqual(-7776, negativeSix.raising(toPower:5).intValue)
+        XCTAssertEqual(46656, negativeSix.raising(toPower:6).intValue)
+        XCTAssertEqual(-279936, negativeSix.raising(toPower:7).intValue)
+        XCTAssertEqual(1679616, negativeSix.raising(toPower:8).intValue)
+        XCTAssertEqual(-10077696, negativeSix.raising(toPower:9).intValue)
+    }
+
+    func test_RepeatingDivision()  {
+        let repeatingNumerator = Decimal(16)
+        let repeatingDenominator = Decimal(9)
+        let repeating = repeatingNumerator / repeatingDenominator
+
+        let numerator = Decimal(1010)
+        var result = numerator / repeating
+
+        var expected = Decimal()
+        expected._exponent = -35;
+        expected._length = 8;
+        expected._isNegative = 0;
+        expected._isCompact = 1;
+        expected._reserved = 0;
+        expected._mantissa.0 = 51946;
+        expected._mantissa.1 = 3;
+        expected._mantissa.2 = 15549;
+        expected._mantissa.3 = 55864;
+        expected._mantissa.4 = 57984;
+        expected._mantissa.5 = 55436;
+        expected._mantissa.6 = 45186;
+        expected._mantissa.7 = 10941;
+
+        XCTAssertEqual(.orderedSame, NSDecimalCompare(&expected, &result), "568.12500000000000000000000000000248554: \(expected.description) != \(result.description)");
+    }
+
+    func test_Round() {
+        let testCases = [
+            // expected, start, scale, round
+            ( 0, 0.5, 0, Decimal.RoundingMode.down ),
+            ( 1, 0.5, 0, Decimal.RoundingMode.up ),
+            ( 2, 2.5, 0, Decimal.RoundingMode.bankers ),
+            ( 4, 3.5, 0, Decimal.RoundingMode.bankers ),
+            ( 5, 5.2, 0, Decimal.RoundingMode.plain ),
+            ( 4.5, 4.5, 1, Decimal.RoundingMode.down ),
+            ( 5.5, 5.5, 1, Decimal.RoundingMode.up ),
+            ( 6.5, 6.5, 1, Decimal.RoundingMode.plain ),
+            ( 7.5, 7.5, 1, Decimal.RoundingMode.bankers ),
+
+            ( -1, -0.5, 0, Decimal.RoundingMode.down ),
+            ( -2, -2.5, 0, Decimal.RoundingMode.up ),
+            ( -3, -2.5, 0, Decimal.RoundingMode.bankers ),
+            ( -4, -3.5, 0, Decimal.RoundingMode.bankers ),
+            ( -5, -5.2, 0, Decimal.RoundingMode.plain ),
+            ( -4.5, -4.5, 1, Decimal.RoundingMode.down ),
+            ( -5.5, -5.5, 1, Decimal.RoundingMode.up ),
+            ( -6.5, -6.5, 1, Decimal.RoundingMode.plain ),
+            ( -7.5, -7.5, 1, Decimal.RoundingMode.bankers ),
+            ]
+        for testCase in testCases {
+            let (expected, start, scale, mode) = testCase
+            var num = Decimal(start)
+            NSDecimalRound(&num, &num, scale, mode)
+            XCTAssertEqual(Decimal(expected), num)
+        }
+    }
+
+    func test_SimpleMultiplication() {
+        var multiplicand = Decimal()
+        multiplicand._isNegative = 0
+        multiplicand._isCompact = 0
+        multiplicand._length = 1
+        multiplicand._exponent = 1
+
+        var multiplier = multiplicand
+        multiplier._exponent = 2
+
+        var expected = multiplicand
+        expected._isNegative = 0
+        expected._isCompact = 0
+        expected._exponent = 3
+        expected._length = 1
+
+        var result = Decimal()
+
+        for i in 1..<UInt8.max {
+            multiplicand._mantissa.0 = UInt16(i)
+
+            for j in 1..<UInt8.max {
+                multiplier._mantissa.0 = UInt16(j)
+                expected._mantissa.0 = UInt16(i) * UInt16(j)
+
+                XCTAssertEqual(.noError, NSDecimalMultiply(&result, &multiplicand, &multiplier, .plain), "\(i) * \(j)")
+                XCTAssertEqual(.orderedSame, NSDecimalCompare(&expected, &result), "\(expected._mantissa.0) == \(i) * \(j)");
+            }
+        }
+    }
+
+    func test_SmallerNumbers() {
+        var number = NSDecimalNumber(booleanLiteral:true)
+        XCTAssertTrue(number.boolValue, "Should have received true")
+
+        number = NSDecimalNumber(mantissa:0, exponent:0, isNegative:false)
+        XCTAssertFalse(number.boolValue, "Should have received false")
+
+        number = NSDecimalNumber(mantissa:1, exponent:0, isNegative:false)
+        XCTAssertTrue(number.boolValue, "Should have received true")
+
+        XCTAssertEqual(100,number.objCType.pointee, "ObjC type for NSDecimalNumber is 'd'")
+    }
+
+    func test_ZeroPower() {
+        let six = NSDecimalNumber(integerLiteral: 6)
+        XCTAssertEqual(1, six.raising(toPower: 0))
+
+        let negativeSix = NSDecimalNumber(integerLiteral: -6)
+        XCTAssertEqual(1, negativeSix.raising(toPower: 0))
+    }
+
+}
diff --git a/TestFoundation/TestNSFileHandle.swift b/TestFoundation/TestNSFileHandle.swift
old mode 100644
new mode 100755
index 69a74cc..93357ff
--- a/TestFoundation/TestNSFileHandle.swift
+++ b/TestFoundation/TestNSFileHandle.swift
@@ -19,6 +19,7 @@
     static var allTests : [(String, (TestNSFileHandle) -> () throws -> ())] {
         return [
                    ("test_pipe", test_pipe),
+                   ("test_nullDevice", test_nullDevice),
         ]
     }
 
@@ -38,4 +39,23 @@
             XCTAssertEqual(output, input)
         }
     }
+
+    func test_nullDevice() {
+        let fh = FileHandle.nullDevice
+
+        XCTAssertEqual(fh.fileDescriptor, -1)
+        fh.closeFile()
+        fh.seek(toFileOffset: 10)
+        XCTAssertEqual(fh.offsetInFile, 0)
+        XCTAssertEqual(fh.seekToEndOfFile(), 0)
+        XCTAssertEqual(fh.readData(ofLength: 15).count, 0)
+        fh.synchronizeFile()
+
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.availableData.count, 0)
+        fh.write(Data(bytes: [1,2]))
+        fh.seek(toFileOffset: 0)
+        XCTAssertEqual(fh.readDataToEndOfFile().count, 0)
+    }
 }
diff --git a/TestFoundation/TestNSKeyedArchiver.swift b/TestFoundation/TestNSKeyedArchiver.swift
index 19ba3d0..6e6b529 100644
--- a/TestFoundation/TestNSKeyedArchiver.swift
+++ b/TestFoundation/TestNSKeyedArchiver.swift
@@ -16,7 +16,7 @@
     import SwiftXCTest
 #endif
 
-public class UserClass : NSObject, NSSecureCoding {
+public class NSUserClass : NSObject, NSSecureCoding {
     var ivar : Int
     
     public class var supportsSecureCoding: Bool {
@@ -37,12 +37,12 @@
     
     public override var description: String {
         get {
-            return "UserClass \(ivar)"
+            return "NSUserClass \(ivar)"
         }
     }
     
     public override func isEqual(_ object: Any?) -> Bool {
-        if let custom = object as? UserClass {
+        if let custom = object as? NSUserClass {
             return self.ivar == custom.ivar
         } else {
             return false
@@ -50,6 +50,40 @@
     }
 }
 
+public class UserClass : CustomStringConvertible, Equatable, Hashable, NSSecureCoding {
+    var ivar : Int
+    
+    public class var supportsSecureCoding: Bool {
+        return true
+    }
+    
+    public func encode(with aCoder : NSCoder) {
+        aCoder.encode(ivar, forKey:"$ivar") // also test escaping
+    }
+    
+    init(_ value: Int) {
+        self.ivar = value
+    }
+    
+    public required init?(coder aDecoder: NSCoder) {
+        self.ivar = aDecoder.decodeInteger(forKey: "$ivar")
+    }
+    
+    public var description: String {
+        get {
+            return "UserClass \(ivar)"
+        }
+    }
+    
+    public static func ==(lhs: UserClass, rhs: UserClass) -> Bool {
+        return lhs.ivar == rhs.ivar
+    }
+    
+    public var hashValue: Int {
+        return ivar
+    }
+}
+
 class TestNSKeyedArchiver : XCTestCase {
     static var allTests: [(String, (TestNSKeyedArchiver) -> () throws -> Void)] {
         return [
@@ -62,6 +96,7 @@
             ("test_archive_string", test_archive_string),
             ("test_archive_mutable_array", test_archive_mutable_array),
             ("test_archive_mutable_dictionary", test_archive_mutable_dictionary),
+            ("test_archive_ns_user_class", test_archive_ns_user_class),
             ("test_archive_nspoint", test_archive_nspoint),
             ("test_archive_nsrange", test_archive_nsrange),
             ("test_archive_nsrect", test_archive_nsrect),
@@ -69,7 +104,8 @@
             ("test_archive_set", test_archive_set),
             ("test_archive_url", test_archive_url),
             ("test_archive_user_class", test_archive_user_class),
-            ("test_archive_uuid", test_archive_uuid),
+            ("test_archive_uuid_bvref", test_archive_uuid_byref),
+            ("test_archive_uuid_byvalue", test_archive_uuid_byvalue),
         ]
     }
 
@@ -85,7 +121,7 @@
         XCTAssertTrue(decode(unarchiver))
     }
     
-    private func test_archive(_ object: NSObject, classes: [AnyClass], allowsSecureCoding: Bool = true, outputFormat: PropertyListSerialization.PropertyListFormat) {
+    private func test_archive(_ object: Any, classes: [AnyClass], allowsSecureCoding: Bool = true, outputFormat: PropertyListSerialization.PropertyListFormat) {
         test_archive({ archiver -> Bool in
                 archiver.requiresSecureCoding = allowsSecureCoding
                 archiver.outputFormat = outputFormat
@@ -97,12 +133,12 @@
                 unarchiver.requiresSecureCoding = allowsSecureCoding
                 
                 do {
-                    let rootObj = try unarchiver.decodeTopLevelObject(of: classes, forKey: NSKeyedArchiveRootObjectKey)
-                    guard let root = rootObj as? NSObject else {
+                    guard let rootObj = try unarchiver.decodeTopLevelObject(of: classes, forKey: NSKeyedArchiveRootObjectKey) else {
                         XCTFail("Unable to decode data")
                         return false
                     }
-                    XCTAssertEqual(object, root, "unarchived object \(root) does not match \(object)")
+                
+                    XCTAssertEqual(object as? AnyHashable, rootObj as? AnyHashable, "unarchived object \(rootObj) does not match \(object)")
                 } catch {
                     XCTFail("Error thrown: \(error)")
                 }
@@ -110,13 +146,13 @@
         })
     }
     
-    private func test_archive(_ object: NSObject, classes: [AnyClass], allowsSecureCoding: Bool = true) {
+    private func test_archive(_ object: Any, classes: [AnyClass], allowsSecureCoding: Bool = true) {
         // test both XML and binary encodings
         test_archive(object, classes: classes, allowsSecureCoding: allowsSecureCoding, outputFormat: PropertyListSerialization.PropertyListFormat.xml)
         test_archive(object, classes: classes, allowsSecureCoding: allowsSecureCoding, outputFormat: PropertyListSerialization.PropertyListFormat.binary)
     }
     
-    private func test_archive(_ object: NSObject, allowsSecureCoding: Bool = true) {
+    private func test_archive(_ object: AnyObject, allowsSecureCoding: Bool = true) {
         return test_archive(object, classes: [type(of: object)], allowsSecureCoding: allowsSecureCoding)
     }
     
@@ -252,8 +288,18 @@
         test_archive(userClass)
     }
     
-    func test_archive_uuid() {
+    func test_archive_ns_user_class() {
+        let nsUserClass = NSUserClass(5678)
+        test_archive(nsUserClass)
+    }
+    
+    func test_archive_uuid_byref() {
         let uuid = NSUUID()
         test_archive(uuid)
     }
+    
+    func test_archive_uuid_byvalue() {
+        let uuid = UUID()
+        return test_archive(uuid, classes: [NSUUID.self])
+    }
 }
diff --git a/TestFoundation/TestNSRange.swift b/TestFoundation/TestNSRange.swift
index 5ce2ae4..927e989 100644
--- a/TestFoundation/TestNSRange.swift
+++ b/TestFoundation/TestNSRange.swift
@@ -23,7 +23,13 @@
         return [
             // currently disabled due to pending requirements for NSString
             // ("test_NSRangeFromString", test_NSRangeFromString ),
-            ("test_NSRangeBridging", test_NSRangeBridging)
+            ("test_NSRangeBridging", test_NSRangeBridging),
+            ("test_NSMaxRange", test_NSMaxRange),
+            ("test_NSLocationInRange", test_NSLocationInRange),
+            ("test_NSEqualRanges", test_NSEqualRanges),
+            ("test_NSUnionRange", test_NSUnionRange),
+            ("test_NSIntersectionRange", test_NSIntersectionRange),
+            ("test_NSStringFromRange", test_NSStringFromRange),
         ]
     }
     
@@ -66,4 +72,69 @@
         let swiftRange2 = range.toRange()
         XCTAssertEqual(swiftRange, swiftRange2)
     }
+
+    func test_NSMaxRange() {
+        let ranges = [(NSMakeRange(0, 3), 3),
+                      (NSMakeRange(7, 8), 15),
+                      (NSMakeRange(56, 1), 57)]
+        for (range, result) in ranges {
+            XCTAssertEqual(NSMaxRange(range), result)
+        }
+    }
+
+    func test_NSLocationInRange() {
+        let ranges = [(3, NSMakeRange(0, 5), true),
+                      (10, NSMakeRange(2, 9), true),
+                      (7, NSMakeRange(2, 5), false),
+                      (5, NSMakeRange(5, 1), true)];
+        for (location, range, result) in ranges {
+            XCTAssertEqual(NSLocationInRange(location, range), result);
+        }
+    }
+
+    func test_NSEqualRanges() {
+        let ranges = [(NSMakeRange(0, 3), NSMakeRange(0, 3), true),
+                      (NSMakeRange(0, 4), NSMakeRange(0, 8), false),
+                      (NSMakeRange(3, 6), NSMakeRange(3, 10), false),
+                      (NSMakeRange(0, 5), NSMakeRange(7, 8), false)]
+        for (first, second, result) in ranges {
+            XCTAssertEqual(NSEqualRanges(first, second), result)
+        }
+    }
+
+    
+    func test_NSUnionRange() {
+        let ranges = [(NSMakeRange(0, 5), NSMakeRange(3, 8), NSMakeRange(0, 11)),
+                      (NSMakeRange(6, 10), NSMakeRange(3, 8), NSMakeRange(3, 13)),
+                      (NSMakeRange(3, 8), NSMakeRange(6, 10), NSMakeRange(3, 13)),
+                      (NSMakeRange(0, 5), NSMakeRange(7, 8), NSMakeRange(0, 15)),
+                      (NSMakeRange(0, 3), NSMakeRange(1, 2), NSMakeRange(0, 3))]
+        for (first, second, result) in ranges {
+            XCTAssert(NSEqualRanges(NSUnionRange(first, second), result))
+        }
+    }
+
+    func test_NSIntersectionRange() {
+        let ranges = [(NSMakeRange(0, 5), NSMakeRange(3, 8), NSMakeRange(3, 2)),
+                      (NSMakeRange(6, 10), NSMakeRange(3, 8), NSMakeRange(6, 5)),
+                      (NSMakeRange(3, 8), NSMakeRange(6, 10), NSMakeRange(6, 5)),
+                      (NSMakeRange(0, 5), NSMakeRange(7, 8), NSMakeRange(0, 0)),
+                      (NSMakeRange(0, 3), NSMakeRange(1, 2), NSMakeRange(1, 2))]
+        for (first, second, result) in ranges {
+            XCTAssert(NSEqualRanges(NSIntersectionRange(first, second), result))
+        }
+    }
+
+    func test_NSStringFromRange() {
+        let ranges = ["{0, 0}": NSMakeRange(0, 0),
+                      "{6, 4}": NSMakeRange(6, 4),
+                      "{0, 10}": NSMakeRange(0, 10),
+                      "{10, 200}": NSMakeRange(10, 200),
+                      "{100, 10}": NSMakeRange(100, 10),
+                      "{1000, 100000}": NSMakeRange(1000, 100_000)];
+
+        for (string, range) in ranges {
+            XCTAssertEqual(NSStringFromRange(range), string)
+        }
+    }
 }
diff --git a/TestFoundation/TestNSString.swift b/TestFoundation/TestNSString.swift
index 49acf78..ebb8fab 100644
--- a/TestFoundation/TestNSString.swift
+++ b/TestFoundation/TestNSString.swift
@@ -81,7 +81,11 @@
             ("test_resolvingSymlinksInPath", test_resolvingSymlinksInPath),
             ("test_expandingTildeInPath", test_expandingTildeInPath),
             ("test_standardizingPath", test_standardizingPath),
-            ("test_removingPercentEncoding", test_removingPercentEncoding),
+            ("test_addingPercentEncoding", test_addingPercentEncoding),
+            ("test_removingPercentEncodingInLatin", test_removingPercentEncodingInLatin),
+            ("test_removingPercentEncodingInNonLatin", test_removingPercentEncodingInNonLatin),
+            ("test_removingPersentEncodingWithoutEncoding", test_removingPersentEncodingWithoutEncoding),
+            ("test_addingPercentEncodingAndBack", test_addingPercentEncodingAndBack),
             ("test_stringByAppendingPathExtension", test_stringByAppendingPathExtension),
             ("test_deletingPathExtension", test_deletingPathExtension),
             ("test_ExternalRepresentation", test_ExternalRepresentation),
@@ -602,6 +606,9 @@
         let characterSet = CharacterSet.whitespaces
         let string: NSString = " abc   "
         XCTAssertEqual(string.trimmingCharacters(in: characterSet), "abc")
+        
+        let emojiString: NSString = " \u{1F62C}  "
+        XCTAssertEqual(emojiString.trimmingCharacters(in: characterSet), "\u{1F62C}")
     }
     
     func test_initializeWithFormat() {
@@ -864,15 +871,68 @@
         }
     }
 
-    func test_removingPercentEncoding() {
+    func test_addingPercentEncoding() {
+        let s1 = "a b".addingPercentEncoding(withAllowedCharacters: .alphanumerics)
+        XCTAssertEqual(s1, "a%20b")
+        
+        let s2 = "\u{0434}\u{043E}\u{043C}".addingPercentEncoding(withAllowedCharacters: .alphanumerics)
+        XCTAssertEqual(s2, "%D0%B4%D0%BE%D0%BC")
+    }
+    
+    func test_removingPercentEncodingInLatin() {
         let s1 = "a%20b".removingPercentEncoding
         XCTAssertEqual(s1, "a b")
         let s2 = "a%1 b".removingPercentEncoding
         XCTAssertNil(s2, "returns nil for a string with an invalid percent encoding")
     }
     
+    func test_removingPercentEncodingInNonLatin() {
+        let s1 = "\u{043C}\u{043E}\u{0439}%20\u{0434}\u{043E}\u{043C}".removingPercentEncoding
+        XCTAssertEqual(s1, "\u{043C}\u{043E}\u{0439} \u{0434}\u{043E}\u{043C}")
+        
+        let s2 = "%D0%B4%D0%BE%D0%BC".removingPercentEncoding
+        XCTAssertEqual(s2, "\u{0434}\u{043E}\u{043C}")
+        
+        let s3 = "\u{00E0}a%1 b".removingPercentEncoding
+        XCTAssertNil(s3, "returns nil for a string with an invalid percent encoding")
+    }
+    
+    func test_removingPersentEncodingWithoutEncoding() {
+        let cyrillicString = "\u{0434}\u{043E}\u{043C}"
+        let cyrillicEscapedString = cyrillicString.removingPercentEncoding
+        XCTAssertEqual(cyrillicString, cyrillicEscapedString)
+        
+        let chineseString = "\u{623F}\u{5B50}"
+        let chineseEscapedString = chineseString.removingPercentEncoding
+        XCTAssertEqual(chineseString, chineseEscapedString)
+        
+        let arabicString = "\u{0645}\u{0646}\u{0632}\u{0644}"
+        let arabicEscapedString = arabicString.removingPercentEncoding
+        XCTAssertEqual(arabicString, arabicEscapedString)
+        
+        let randomString = "\u{00E0}\u{00E6}"
+        let randomEscapedString = randomString.removingPercentEncoding
+        XCTAssertEqual(randomString, randomEscapedString)
+        
+        let latinString = "home"
+        let latinEscapedString = latinString.removingPercentEncoding
+        XCTAssertEqual(latinString, latinEscapedString)
+    }
+    
+    func test_addingPercentEncodingAndBack() {
+        let latingString = "a b"
+        let escapedLatingString = latingString.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
+        let returnedLatingString = escapedLatingString?.removingPercentEncoding
+        XCTAssertEqual(returnedLatingString, latingString)
+        
+        let cyrillicString = "\u{0434}\u{043E}\u{043C}"
+        let escapedCyrillicString = cyrillicString.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
+        let returnedCyrillicString = escapedCyrillicString?.removingPercentEncoding
+        XCTAssertEqual(returnedCyrillicString, cyrillicString)
+    }
+    
     func test_stringByAppendingPathExtension() {
-        let values : Dictionary = [
+        let values = [
             NSString(string: "/tmp/scratch.old") : "/tmp/scratch.old.tiff",
             NSString(string: "/tmp/scratch.") : "/tmp/scratch..tiff",
             NSString(string: "/tmp/") : "/tmp.tiff",
@@ -882,7 +942,7 @@
         ]
         for (fileName, expectedResult) in values {
             let result = fileName.appendingPathExtension("tiff")
-            XCTAssertEqual(result, expectedResult, "expected \(expectedResult) for \(fileName) but got \(result)")
+            XCTAssertEqual(result, expectedResult, "expected \(expectedResult) for \(fileName) but got \(result as Optional)")
         }
     }
     
diff --git a/TestFoundation/TestNSTimeZone.swift b/TestFoundation/TestNSTimeZone.swift
index 41ac367..2f6968b 100644
--- a/TestFoundation/TestNSTimeZone.swift
+++ b/TestFoundation/TestNSTimeZone.swift
@@ -47,7 +47,7 @@
         let tz = NSTimeZone.system
         let abbreviation1 = tz.abbreviation()
         let abbreviation2 = tz.abbreviation(for: Date())
-        XCTAssertEqual(abbreviation1, abbreviation2, "\(abbreviation1) should be equal to \(abbreviation2)")
+        XCTAssertEqual(abbreviation1, abbreviation2, "\(abbreviation1 as Optional) should be equal to \(abbreviation2 as Optional)")
     }
 
     func test_abbreviationDictionary() {
@@ -98,7 +98,7 @@
 
         let abbreviation1 = tz.abbreviation()
         let abbreviation2 = obj.abbreviation
-        XCTAssertEqual(abbreviation1, abbreviation2, "\(abbreviation1) should be equal to \(abbreviation2)")
+        XCTAssertEqual(abbreviation1, abbreviation2, "\(abbreviation1 as Optional) should be equal to \(abbreviation2 as Optional)")
 
         let isDaylightSavingTime1 = tz.isDaylightSavingTime()
         let isDaylightSavingTime2 = obj.isDaylightSavingTime
@@ -112,7 +112,7 @@
         let nextDaylightSavingTimeTransition1 = tz.nextDaylightSavingTimeTransition
         let nextDaylightSavingTimeTransition2 = obj.nextDaylightSavingTimeTransition
         let nextDaylightSavingTimeTransition3 = tz.nextDaylightSavingTimeTransition(after: Date())
-        XCTAssert(nextDaylightSavingTimeTransition1 == nextDaylightSavingTimeTransition2 || nextDaylightSavingTimeTransition2 == nextDaylightSavingTimeTransition3, "\(nextDaylightSavingTimeTransition1) should be equal to \(nextDaylightSavingTimeTransition2), or in the rare circumstance where a daylight saving time transition has just occurred, \(nextDaylightSavingTimeTransition2) should be equal to \(nextDaylightSavingTimeTransition3)")
+        XCTAssert(nextDaylightSavingTimeTransition1 == nextDaylightSavingTimeTransition2 || nextDaylightSavingTimeTransition2 == nextDaylightSavingTimeTransition3, "\(nextDaylightSavingTimeTransition1 as Optional) should be equal to \(nextDaylightSavingTimeTransition2 as Optional), or in the rare circumstance where a daylight saving time transition has just occurred, \(nextDaylightSavingTimeTransition2 as Optional) should be equal to \(nextDaylightSavingTimeTransition3 as Optional)")
     }
 
     func test_knownTimeZoneNames() {
@@ -137,18 +137,18 @@
     func test_initializingTimeZoneWithOffset() {
         let tz = TimeZone(identifier: "GMT-0400")
         XCTAssertNotNil(tz)
-        let seconds = tz?.secondsFromGMT(for: Date())
+        let seconds = tz?.secondsFromGMT(for: Date()) ?? 0
         XCTAssertEqual(seconds, -14400, "GMT-0400 should be -14400 seconds but got \(seconds) instead")
 
         let tz2 = TimeZone(secondsFromGMT: -14400)
         XCTAssertNotNil(tz2)
         let expectedName = "GMT-0400"
         let actualName = tz2?.identifier
-        XCTAssertEqual(actualName, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(actualName)\"")
+        XCTAssertEqual(actualName, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(actualName as Optional)\"")
         let expectedLocalizedName = "GMT-04:00"
         let actualLocalizedName = tz2?.localizedName(for: .generic, locale: Locale(identifier: "en_US"))
-        XCTAssertEqual(actualLocalizedName, expectedLocalizedName, "expected name \"\(expectedLocalizedName)\" is not equal to \"\(actualLocalizedName)\"")
-        let seconds2 = tz2?.secondsFromGMT()
+        XCTAssertEqual(actualLocalizedName, expectedLocalizedName, "expected name \"\(expectedLocalizedName)\" is not equal to \"\(actualLocalizedName as Optional)\"")
+        let seconds2 = tz2?.secondsFromGMT() ?? 0
         XCTAssertEqual(seconds2, -14400, "GMT-0400 should be -14400 seconds but got \(seconds2) instead")
 
         let tz3 = TimeZone(identifier: "GMT-9999")
@@ -161,8 +161,9 @@
         XCTAssertNil(tz)
         // Test valid timezone abbreviation of "AST" for "America/Halifax"
         tz = TimeZone(abbreviation: "AST")
-        let expectedName = "America/Halifax"
-        XCTAssertEqual(tz?.identifier, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(tz?.identifier)\"")
+        let expectedIdentifier = "America/Halifax"
+        let actualIdentifier = tz?.identifier
+        XCTAssertEqual(actualIdentifier, expectedIdentifier, "expected identifier \"\(expectedIdentifier)\" is not equal to \"\(actualIdentifier as Optional)\"")
     }
 
     func test_systemTimeZoneUsesSystemTime() {
diff --git a/TestFoundation/TestNSURL.swift b/TestFoundation/TestNSURL.swift
index 9c7c10f..87409b5 100644
--- a/TestFoundation/TestNSURL.swift
+++ b/TestFoundation/TestNSURL.swift
@@ -153,7 +153,7 @@
             }
             if let stringObj = obj as? String {
                 if stringObj != got[key] {
-                    differences.append(" \(key)  Expected = '\(stringObj)',  Got = '\(got[key])'")
+                    differences.append(" \(key)  Expected = '\(stringObj)',  Got = '\(got[key] as Optional)'")
                 }
             }
         }
@@ -442,7 +442,7 @@
         var url = URLComponents(string: urlString)
         url!.port = port
         let receivedString = url!.string
-        XCTAssertEqual(receivedString, expectedString, "expected \(expectedString) but received \(receivedString)")
+        XCTAssertEqual(receivedString, expectedString, "expected \(expectedString) but received \(receivedString as Optional)")
     }
 
     func test_url() {
@@ -454,7 +454,7 @@
         compWithAuthority!.path = "/path/to/file with space.html"
         compWithAuthority!.query = "id=23&search=Foo Bar"
         var expectedString = "https://www.swift.org/path/to/file%20with%20space.html?id=23&search=Foo%20Bar"
-        XCTAssertEqual(compWithAuthority!.string, expectedString, "expected \(expectedString) but received \(compWithAuthority!.string)")
+        XCTAssertEqual(compWithAuthority!.string, expectedString, "expected \(expectedString) but received \(compWithAuthority!.string as Optional)")
 
         var aURL = compWithAuthority!.url(relativeTo: baseURL)
         XCTAssertNotNil(aURL)
@@ -474,7 +474,7 @@
         compWithoutAuthority.path = "path/to/file with space.html"
         compWithoutAuthority.query = "id=23&search=Foo Bar"
         expectedString = "path/to/file%20with%20space.html?id=23&search=Foo%20Bar"
-        XCTAssertEqual(compWithoutAuthority.string, expectedString, "expected \(expectedString) but received \(compWithoutAuthority.string)")
+        XCTAssertEqual(compWithoutAuthority.string, expectedString, "expected \(expectedString) but received \(compWithoutAuthority.string as Optional)")
 
         aURL = compWithoutAuthority.url(relativeTo: baseURL)
         XCTAssertNotNil(aURL)
diff --git a/TestFoundation/TestNSURLCredential.swift b/TestFoundation/TestNSURLCredential.swift
index 542c857..037b114 100644
--- a/TestFoundation/TestNSURLCredential.swift
+++ b/TestFoundation/TestNSURLCredential.swift
@@ -21,7 +21,8 @@
     static var allTests: [(String, (TestNSURLCredential) -> () throws -> Void)] {
         return [
                    ("test_construction", test_construction),
-                   ("test_copy", test_copy)
+                   ("test_copy", test_copy),
+                   ("test_NSCoding", test_NSCoding)
         ]
     }
     
@@ -39,4 +40,10 @@
         let copy = credential.copy() as! URLCredential
         XCTAssertTrue(copy.isEqual(credential))
     }
+    
+    func test_NSCoding() {
+        let credentialA = URLCredential(user: "swiftUser", password: "swiftPassword", persistence: .forSession)
+        let credentialB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: credentialA)) as! URLCredential
+        XCTAssertEqual(credentialA, credentialB, "Archived then unarchived url credential must be equal.")
+    }
 }
diff --git a/TestFoundation/TestNSXMLDocument.swift b/TestFoundation/TestNSXMLDocument.swift
index 3a6b20a..a493dcd 100644
--- a/TestFoundation/TestNSXMLDocument.swift
+++ b/TestFoundation/TestNSXMLDocument.swift
@@ -161,7 +161,7 @@
         element.insertChildren([foo, bar], at: 1)
         XCTAssertEqual(element.children?[1], foo)
         XCTAssertEqual(element.children?[2], bar)
-        XCTAssertEqual(element.children?[0], baz, "\(element.children?[0])")
+        XCTAssertEqual(element.children?[0], baz)
 
         let faz = XMLElement(name: "faz")
         element.replaceChild(at: 2, with: faz)
@@ -239,7 +239,7 @@
         XCTAssertEqual(element.attributes?.last, bazAttribute)
 
         element.setAttributesWith(["hello": "world", "foobar": "buzbaz"])
-        XCTAssertEqual(element.attribute(forName:"hello")?.stringValue, "world", "\(element.attribute(forName:"hello")?.stringValue)")
+        XCTAssertEqual(element.attribute(forName:"hello")?.stringValue, "world", "\(element.attribute(forName:"hello")?.stringValue as Optional)")
         XCTAssertEqual(element.attribute(forName:"foobar")?.stringValue, "buzbaz", "\(element.attributes ?? [])")
     }
 
diff --git a/TestFoundation/TestNotification.swift b/TestFoundation/TestNotification.swift
new file mode 100644
index 0000000..9c1bd38
--- /dev/null
+++ b/TestFoundation/TestNotification.swift
@@ -0,0 +1,56 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 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 TestNotification : XCTestCase {
+
+    static var allTests: [(String, (TestNotification) -> () throws -> Void)] {
+        return [
+            ("test_customReflection", test_customReflection),
+        ]
+    }
+
+    func test_customReflection() {
+        let someName = "somenotifname"
+        let targetObject = NSObject()
+        let userInfo = ["hello": "world", "indexThis": 350] as [AnyHashable: Any]
+        let notif = Notification(name: Notification.Name(rawValue: someName), object: targetObject, userInfo: userInfo)
+        let mirror = notif.customMirror
+
+        XCTAssertEqual(mirror.displayStyle, .class)
+        XCTAssertNil(mirror.superclassMirror)
+
+        var children = Array(mirror.children).makeIterator()
+        let firstChild = children.next()
+        let secondChild = children.next()
+        let thirdChild = children.next()
+        XCTAssertEqual(firstChild?.label, "name")
+        XCTAssertEqual(firstChild?.value as? String, someName)
+
+        XCTAssertEqual(secondChild?.label, "object")
+        XCTAssertEqual(secondChild?.value as? NSObject, targetObject)
+
+        XCTAssertEqual(thirdChild?.label, "userInfo")
+        XCTAssertEqual((thirdChild?.value as? [AnyHashable: Any])?["hello"] as? String, "world")
+        XCTAssertEqual((thirdChild?.value as? [AnyHashable: Any])?["indexThis"] as? Int, 350)
+
+    }
+
+}
diff --git a/TestFoundation/TestObjCRuntime.swift b/TestFoundation/TestObjCRuntime.swift
new file mode 100644
index 0000000..21c0042
--- /dev/null
+++ b/TestFoundation/TestObjCRuntime.swift
@@ -0,0 +1,53 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 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 SwiftClass {
+    class InnerClass {}
+}
+
+struct SwfitStruct {}
+
+enum SwiftEnum {}
+
+class TestObjCRuntime: XCTestCase {
+    static var allTests: [(String, (TestObjCRuntime) -> () throws -> Void)] {
+        return [
+            ("testStringFromClass", testStringFromClass),
+            ("testClassFromString", testClassFromString),
+        ]
+    }
+
+    func testStringFromClass() {
+        XCTAssertEqual(NSStringFromClass(NSObject.self), "NSObject")
+        XCTAssertEqual(NSStringFromClass(SwiftClass.self), "TestFoundation.SwiftClass")
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+        XCTAssertEqual(NSStringFromClass(XCTestCase.self), "XCTest.XCTestCase");
+#else
+        XCTAssertEqual(NSStringFromClass(XCTestCase.self), "SwiftXCTest.XCTestCase");
+#endif
+    }
+
+    func testClassFromString() {
+        XCTAssertNotNil(NSClassFromString("NSObject"))
+        XCTAssertNotNil(NSClassFromString("TestFoundation.SwiftClass"))
+        XCTAssertNil(NSClassFromString("TestFoundation.SwiftClass.InnerClass"))
+        XCTAssertNil(NSClassFromString("SwiftClass"))
+        XCTAssertNil(NSClassFromString("MadeUpClassName"))
+        XCTAssertNil(NSClassFromString("SwiftStruct"));
+        XCTAssertNil(NSClassFromString("SwiftEnum"));
+    }
+}
diff --git a/TestFoundation/main.swift b/TestFoundation/main.swift
index 5e325c4..732bf17 100644
--- a/TestFoundation/main.swift
+++ b/TestFoundation/main.swift
@@ -32,6 +32,7 @@
     testCase(TestNSDate.allTests),
     testCase(TestNSDateComponents.allTests),
     testCase(TestNSDateFormatter.allTests),
+    testCase(TestNSDecimal.allTests),
     testCase(TestNSDictionary.allTests),
     testCase(TestNSFileManager.allTests),
     testCase(TestNSGeometry.allTests),
@@ -85,4 +86,6 @@
     testCase(TestUnitConverter.allTests),
     testCase(TestProgressFraction.allTests),
     testCase(TestProgress.allTests),
+    testCase(TestObjCRuntime.allTests),
+    testCase(TestNotification.allTests),
 ])