Merge branch 'master' of github.com:apple/swift-corelibs-foundation into cg-api
diff --git a/CoreFoundation/Base.subproj/CFInternal.h b/CoreFoundation/Base.subproj/CFInternal.h
index 198c8e2..786d704 100644
--- a/CoreFoundation/Base.subproj/CFInternal.h
+++ b/CoreFoundation/Base.subproj/CFInternal.h
@@ -157,7 +157,7 @@
 
 CF_PRIVATE os_log_t _CFOSLog(void);
 
-CF_PRIVATE CFIndex __CFActiveProcessorCount();
+CF_PRIVATE CFIndex __CFActiveProcessorCount(void);
 
 #ifndef CLANG_ANALYZER_NORETURN
 #if __has_feature(attribute_analyzer_noreturn)
@@ -325,7 +325,7 @@
 extern const char *__CFgetenv(const char *n);
 extern const char *__CFgetenvIfNotRestricted(const char *n);    // Returns NULL in a restricted process
 
-CF_PRIVATE Boolean __CFProcessIsRestricted();
+CF_PRIVATE Boolean __CFProcessIsRestricted(void);
 
 // This is really about the availability of C99. We don't have that on Windows, but we should everywhere else.
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -587,8 +587,8 @@
 
 /* ==================== Simple path manipulation ==================== */
 
-CF_EXPORT UniChar _CFGetSlash();
-CF_PRIVATE CFStringRef _CFGetSlashStr();
+CF_EXPORT UniChar _CFGetSlash(void);
+CF_PRIVATE CFStringRef _CFGetSlashStr(void);
 CF_EXPORT Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length);
 CF_PRIVATE void _CFAppendTrailingPathSlash2(CFMutableStringRef path);
 CF_PRIVATE void _CFAppendConditionalTrailingPathSlash2(CFMutableStringRef path);
@@ -733,7 +733,7 @@
 CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale);
 
 
-CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages();
+CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages(void);
 
 
 // This should only be used in CF types, not toll-free bridged objects!
diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c
index 5f67510..896193f 100644
--- a/CoreFoundation/Base.subproj/CFPlatform.c
+++ b/CoreFoundation/Base.subproj/CFPlatform.c
@@ -180,6 +180,12 @@
     }
     return __CFProcessPath;
 }
+
+#else
+
+Boolean _CFIsMainThread(void) {
+    return pthread_main_np() == 1;
+}
 #endif
 
 CF_PRIVATE CFStringRef _CFProcessNameString(void) {
@@ -1295,7 +1301,7 @@
     return (CFTypeRef)pthread_getspecific(key);
 }
 
-void _CThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
+void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value) {
     if (value != NULL) {
         swift_retain((void *)value);
         pthread_setspecific(key, value);
diff --git a/CoreFoundation/Base.subproj/CFRuntime.c b/CoreFoundation/Base.subproj/CFRuntime.c
index ead676d..50ffb79 100644
--- a/CoreFoundation/Base.subproj/CFRuntime.c
+++ b/CoreFoundation/Base.subproj/CFRuntime.c
@@ -808,11 +808,11 @@
 }
 
 
-extern CFTypeID CFBinaryHeapGetTypeID();
-extern CFTypeID CFBitVectorGetTypeID();
-extern CFTypeID CFTreeGetTypeID();
-extern CFTypeID CFPlugInInstanceGetTypeID();
-extern CFTypeID CFStringTokenizerGetTypeID();
+extern CFTypeID CFBinaryHeapGetTypeID(void);
+extern CFTypeID CFBitVectorGetTypeID(void);
+extern CFTypeID CFTreeGetTypeID(void);
+extern CFTypeID CFPlugInInstanceGetTypeID(void);
+extern CFTypeID CFStringTokenizerGetTypeID(void);
 extern CFTypeID CFStorageGetTypeID(void);
 extern void __CFAllocatorInitialize(void);
 extern void __CFStringInitialize(void);
@@ -821,7 +821,7 @@
 extern void __CFPFactoryInitialize(void);
 extern void __CFPlugInInitialize(void);
 #if (DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_MACOSX) && DEPLOYMENT_RUNTIME_SWIFT
-CF_PRIVATE void __CFTSDInitialize();
+CF_PRIVATE void __CFTSDInitialize(void);
 #endif
 #if DEPLOYMENT_TARGET_WINDOWS
 // From CFPlatform.c
@@ -1005,7 +1005,7 @@
         memset(__CFRuntimeObjCClassTable, 0, sizeof(__CFRuntimeObjCClassTable));
 
 #if DEPLOYMENT_RUNTIME_SWIFT
-        extern uintptr_t __CFSwiftGetBaseClass();
+        extern uintptr_t __CFSwiftGetBaseClass(void);
         
         uintptr_t NSCFType = __CFSwiftGetBaseClass();
         for (CFIndex idx = 1; idx < __CFRuntimeClassTableSize; idx++) {
@@ -1107,7 +1107,7 @@
 #endif
         
 #if DEPLOYMENT_RUNTIME_SWIFT
-        extern void __CFInitializeSwift();
+        extern void __CFInitializeSwift(void);
         __CFInitializeSwift();
         __CFNumberInitialize(); /* needs to happen after Swift bridge is initialized */
 #endif
diff --git a/CoreFoundation/Base.subproj/ForFoundationOnly.h b/CoreFoundation/Base.subproj/ForFoundationOnly.h
index cb782e9..ce31dd1 100644
--- a/CoreFoundation/Base.subproj/ForFoundationOnly.h
+++ b/CoreFoundation/Base.subproj/ForFoundationOnly.h
@@ -631,12 +631,12 @@
 
 
 
-CF_EXPORT CFIndex __CFProcessorCount();
-CF_EXPORT uint64_t __CFMemorySize();
+CF_EXPORT CFIndex __CFProcessorCount(void);
+CF_EXPORT uint64_t __CFMemorySize(void);
 CF_EXPORT CFStringRef _CFProcessNameString(void);
-CF_EXPORT CFIndex __CFActiveProcessorCount();
-CF_EXPORT CFDictionaryRef __CFGetEnvironment();
-CF_EXPORT int32_t __CFGetPid();
+CF_EXPORT CFIndex __CFActiveProcessorCount(void);
+CF_EXPORT CFDictionaryRef __CFGetEnvironment(void);
+CF_EXPORT int32_t __CFGetPid(void);
 CF_EXPORT CFTimeInterval CFGetSystemUptime(void);
 CF_EXPORT CFStringRef CFCopySystemVersionString(void);
 CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
index c1e3610..2d20856 100644
--- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
+++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
@@ -27,6 +27,15 @@
 #include <CoreFoundation/ForFoundationOnly.h>
 #include <fts.h>
 #include <pthread.h>
+#include <execinfo.h>
+
+#if __has_include(<malloc/malloc.h>)
+#include <malloc/malloc.h>
+#endif
+
+#if __has_include(<malloc/malloc.h>)
+#include <malloc/malloc.h>
+#endif
 
 _CF_EXPORT_SCOPE_BEGIN
 
@@ -138,7 +147,7 @@
 };
 
 struct _NSXMLParserBridge {
-    _CFXMLInterface _Nullable (*_Nonnull currentParser)();
+    _CFXMLInterface _Nullable (*_Nonnull currentParser)(void);
     _CFXMLInterfaceParserInput _Nullable (*_Nonnull _xmlExternalEntityWithURL)(_CFXMLInterface interface, const char *url, const char * identifier, _CFXMLInterfaceParserContext context, _CFXMLInterfaceExternalEntityLoader originalLoaderFunction);
     
     _CFXMLInterfaceParserContext _Nonnull (*_Nonnull getContext)(_CFXMLInterface ctx);
@@ -294,13 +303,14 @@
 CF_EXPORT void CFLog1(CFLogLevel lev, CFStringRef message);
 
 CF_EXPORT Boolean _CFIsMainThread(void);
+CF_EXPORT pthread_t _CFMainPThread;
 
 CF_EXPORT CFHashCode __CFHashDouble(double d);
 
 typedef pthread_key_t _CFThreadSpecificKey;
 CF_EXPORT CFTypeRef _Nullable _CFThreadSpecificGet(_CFThreadSpecificKey key);
-CF_EXPORT void _CThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value);
-CF_EXPORT _CFThreadSpecificKey _CFThreadSpecificKeyCreate();
+CF_EXPORT void _CFThreadSpecificSet(_CFThreadSpecificKey key, CFTypeRef _Nullable value);
+CF_EXPORT _CFThreadSpecificKey _CFThreadSpecificKeyCreate(void);
 
 typedef pthread_attr_t _CFThreadAttributes;
 typedef pthread_t _CFThreadRef;
@@ -343,6 +353,54 @@
 /// a single base directory relative to which user-specific runtime files and other file objects should be placed. This directory is defined by the environment variable $XDG_RUNTIME_DIR.
 CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void);
 
+
+typedef struct {
+    void *_Nonnull memory;
+    size_t capacity;
+    _Bool onStack;
+} _ConditionalAllocationBuffer;
+
+static inline _Bool _resizeConditionalAllocationBuffer(_ConditionalAllocationBuffer *_Nonnull buffer, size_t amt) {
+#if TARGET_OS_MAC
+    size_t amount = malloc_good_size(amt);
+#else
+    size_t amount = amt;
+#endif
+    if (amount <= buffer->capacity) { return true; }
+    void *newMemory;
+    if (buffer->onStack) {
+        newMemory = malloc(amount);
+        if (newMemory == NULL) { return false; }
+        memcpy(newMemory, buffer->memory, buffer->capacity);
+        buffer->onStack = false;
+    } else {
+        newMemory = realloc(buffer->memory, amount);
+        if (newMemory == NULL) { return false; }
+    }
+    if (newMemory == NULL) { return false; }
+    buffer->memory = newMemory;
+    buffer->capacity = amount;
+    return true;
+}
+
+static inline _Bool _withStackOrHeapBuffer(size_t amount, void (__attribute__((noescape)) ^ _Nonnull applier)(_ConditionalAllocationBuffer *_Nonnull)) {
+    _ConditionalAllocationBuffer buffer;
+#if TARGET_OS_MAC
+    buffer.capacity = malloc_good_size(amount);
+#else
+    buffer.capacity = amount;
+#endif
+    buffer.onStack = (_CFIsMainThread() != 0 ? buffer.capacity < 2048 : buffer.capacity < 512);
+    buffer.memory = buffer.onStack ? alloca(buffer.capacity) : malloc(buffer.capacity);
+    if (buffer.memory == NULL) { return false; }
+    applier(&buffer);
+    if (!buffer.onStack) {
+        free(buffer.memory);
+    }
+    return true;
+}
+
+
 _CF_EXPORT_SCOPE_END
 
 #endif /* __COREFOUNDATION_FORSWIFTFOUNDATIONONLY__ */
diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.c b/CoreFoundation/NumberDate.subproj/CFTimeZone.c
index 427a3b1..a878e23 100644
--- a/CoreFoundation/NumberDate.subproj/CFTimeZone.c
+++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.c
@@ -793,7 +793,7 @@
         size_t zoneInfoDirLen = CFStringGetLength(__tzZoneInfo);
         if (strncmp(linkbuf, tzZoneInfo, zoneInfoDirLen) == 0) {
             name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (uint8_t *)linkbuf + zoneInfoDirLen,
-                                           strlen(linkbuf) - zoneInfoDirLen + 2, kCFStringEncodingUTF8, false);
+                                           strlen(linkbuf) - zoneInfoDirLen + 1, kCFStringEncodingUTF8, false);
         } else {
             name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (uint8_t *)linkbuf, strlen(linkbuf), kCFStringEncodingUTF8, false);
         }
diff --git a/CoreFoundation/Parsing.subproj/CFXMLInterface.c b/CoreFoundation/Parsing.subproj/CFXMLInterface.c
index 0c1dbae..5be8bff 100644
--- a/CoreFoundation/Parsing.subproj/CFXMLInterface.c
+++ b/CoreFoundation/Parsing.subproj/CFXMLInterface.c
@@ -893,8 +893,8 @@
         CFArrayAppendValue(results, nodes->nodeTab[i]);
     }
 
-    xmlFree(context);
-    xmlFree(evalResult);
+    xmlXPathFreeContext(context);
+    xmlXPathFreeObject(evalResult);
 
     return results;
 }
diff --git a/CoreFoundation/Parsing.subproj/CFXMLInterface.h b/CoreFoundation/Parsing.subproj/CFXMLInterface.h
index f9ac170..d4fe3d2 100644
--- a/CoreFoundation/Parsing.subproj/CFXMLInterface.h
+++ b/CoreFoundation/Parsing.subproj/CFXMLInterface.h
@@ -100,7 +100,7 @@
 
 void _CFSetupXMLInterface(void);
 _CFXMLInterfaceParserInput _CFXMLInterfaceNoNetExternalEntityLoader(const char *URL, const char *ID, _CFXMLInterfaceParserContext ctxt);
-_CFXMLInterfaceSAXHandler _CFXMLInterfaceCreateSAXHandler();
+_CFXMLInterfaceSAXHandler _CFXMLInterfaceCreateSAXHandler(void);
 void _CFXMLInterfaceDestroySAXHandler(_CFXMLInterfaceSAXHandler handler);
 void _CFXMLInterfaceSetStructuredErrorFunc(_CFXMLInterface ctx, _CFXMLInterfaceStructuredErrorFunc _Nullable  handler);
 _CFXMLInterfaceParserContext  _CFXMLInterfaceCreatePushParserCtxt(_CFXMLInterfaceSAXHandler _Nullable sax, _CFXMLInterface  user_data, const char * chunk, int size, const char *_Nullable filename);
diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.c b/CoreFoundation/PlugIn.subproj/CFBundle.c
index 84408cc..cf90cae 100644
--- a/CoreFoundation/PlugIn.subproj/CFBundle.c
+++ b/CoreFoundation/PlugIn.subproj/CFBundle.c
@@ -882,7 +882,7 @@
 };
 
 // From CFBundle_Resources.c
-CF_PRIVATE void _CFBundleResourcesInitialize();
+CF_PRIVATE void _CFBundleResourcesInitialize(void);
 
 CFTypeID CFBundleGetTypeID(void) {
     static dispatch_once_t initOnce;
diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h
index 3cab577..04918f6 100644
--- a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h
+++ b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h
@@ -144,7 +144,7 @@
 CF_PRIVATE Boolean _CFBundleGetObjCImageInfo(CFBundleRef bundle, uint32_t *objcVersion, uint32_t *objcFlags);
 
 #if defined(BINARY_SUPPORT_DYLD)
-CF_PRIVATE CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable();
+CF_PRIVATE CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable(void);
 CF_PRIVATE Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags);
 #endif
 
diff --git a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c
index 1029622..6366a5b 100644
--- a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c
+++ b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c
@@ -17,7 +17,7 @@
 #include <CoreFoundation/CFNumberFormatter.h>
 #include <CoreFoundation/CFDateFormatter.h>
 #include <sys/types.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
 #include <unistd.h>
 #endif
 
diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.c b/CoreFoundation/Preferences.subproj/CFPreferences.c
index 8f00af0..18723c6 100644
--- a/CoreFoundation/Preferences.subproj/CFPreferences.c
+++ b/CoreFoundation/Preferences.subproj/CFPreferences.c
@@ -445,7 +445,7 @@
 static CFURLRef _CFPreferencesURLForStandardDomainWithSafetyLevel(CFStringRef domainName, CFStringRef userName, CFStringRef hostName, unsigned long safeLevel) {
     CFURLRef theURL = NULL;
     CFAllocatorRef prefAlloc = __CFPreferencesAllocator();
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
     CFURLRef prefDir = _preferencesDirectoryForUserHostSafetyLevel(userName, hostName, safeLevel);
     CFStringRef  appName;
     CFStringRef  fileName;
@@ -479,7 +479,7 @@
 	CFRelease(appName);
     }
     if (fileName) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
         theURL = CFURLCreateWithFileSystemPathRelativeToBase(prefAlloc, fileName, kCFURLPOSIXPathStyle, false, prefDir);
 #elif DEPLOYMENT_TARGET_WINDOWS
 		theURL = CFURLCreateWithFileSystemPathRelativeToBase(prefAlloc, fileName, kCFURLWindowsPathStyle, false, prefDir);
@@ -497,10 +497,6 @@
     return _CFPreferencesURLForStandardDomainWithSafetyLevel(domainName, userName, hostName, __CFSafeLaunchLevel);
 }
 
-const _CFPreferencesDomainCallBacks __kCFXMLPropertyListDomainCallBacks = {
-    
-};
-
 CFPreferencesDomainRef _CFPreferencesStandardDomain(CFStringRef  domainName, CFStringRef  userName, CFStringRef  hostName) {
     CFPreferencesDomainRef domain;
     CFStringRef  domainKey;
diff --git a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c
index 5941118..8073848 100644
--- a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c
+++ b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c
@@ -16,10 +16,12 @@
 #include <CoreFoundation/CFDate.h>
 #include "CFInternal.h"
 #include <time.h>
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/stat.h>
+#endif
+#if DEPLOYMENT_TARGET_MACOSX
 #include <mach/mach.h>
 #include <mach/mach_syscalls.h>
 #endif
@@ -102,7 +104,7 @@
     if (parentURL) CFRelease(parentURL);
     if (!parentExists) return false;
 
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
     mode = worldReadable ? S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH : S_IRWXU;
 #else
     mode = 0666;
@@ -306,7 +308,7 @@
         CFDataRef data = CFPropertyListCreateData(alloc, dict, desiredFormat, 0, NULL);
         if (data) {
             SInt32 mode;
-#if DEPLOYMENT_TARGET_MACOSX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX
             mode = isWorldReadable ? S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH : S_IRUSR|S_IWUSR;
 #else
 	    mode = 0666;
diff --git a/CoreFoundation/String.subproj/CFBurstTrie.h b/CoreFoundation/String.subproj/CFBurstTrie.h
index 2ed8c00..5ceea2d 100644
--- a/CoreFoundation/String.subproj/CFBurstTrie.h
+++ b/CoreFoundation/String.subproj/CFBurstTrie.h
@@ -60,7 +60,7 @@
 typedef void (*CFBurstTrieTraversalCallback)(void* context, const UInt8* key, uint32_t keyLength, uint32_t payload, Boolean *stop);
 
 CF_EXPORT 
-CFBurstTrieRef CFBurstTrieCreate() CF_AVAILABLE(10_7, 4_2);
+CFBurstTrieRef CFBurstTrieCreate(void) CF_AVAILABLE(10_7, 4_2);
 
 CF_EXPORT
 CFBurstTrieRef CFBurstTrieCreateWithOptions(CFDictionaryRef options) CF_AVAILABLE(10_8, 6_0);
diff --git a/CoreFoundation/String.subproj/CFRegularExpression.c b/CoreFoundation/String.subproj/CFRegularExpression.c
index 71a121d..79a1d96 100644
--- a/CoreFoundation/String.subproj/CFRegularExpression.c
+++ b/CoreFoundation/String.subproj/CFRegularExpression.c
@@ -133,8 +133,9 @@
     if (regex == NULL || U_FAILURE(errorCode)) {
         // ??? do we need more detailed errors here?
         if (errorPtr) {
-            CFStringRef keys[] = {
-                CFSTR("NSInvalidValue")
+            CFStringRef key = CFSTR("NSInvalidValue");
+            CFTypeRef keys[] = {
+                key
             };
             CFTypeRef values[] = {
                 pattern
diff --git a/CoreFoundation/URL.subproj/CFURLComponents.h b/CoreFoundation/URL.subproj/CFURLComponents.h
index 095f285..15d4c56 100644
--- a/CoreFoundation/URL.subproj/CFURLComponents.h
+++ b/CoreFoundation/URL.subproj/CFURLComponents.h
@@ -102,12 +102,12 @@
 CF_EXPORT CFStringRef _Nullable _CFStringCreateByRemovingPercentEncoding(CFAllocatorRef alloc, CFStringRef string);
 
 // These return singletons
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLUserAllowedCharacterSet();
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPasswordAllowedCharacterSet();
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLHostAllowedCharacterSet();
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPathAllowedCharacterSet();
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLQueryAllowedCharacterSet();
-CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLFragmentAllowedCharacterSet();
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLUserAllowedCharacterSet(void);
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPasswordAllowedCharacterSet(void);
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLHostAllowedCharacterSet(void);
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLPathAllowedCharacterSet(void);
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLQueryAllowedCharacterSet(void);
+CF_EXPORT CFCharacterSetRef _CFURLComponentsGetURLFragmentAllowedCharacterSet(void);
 
 CF_EXPORT _Nullable CFArrayRef _CFURLComponentsCopyQueryItems(CFURLComponentsRef components);
 CF_EXPORT void _CFURLComponentsSetQueryItems(CFURLComponentsRef components, CFArrayRef names, CFArrayRef values);
diff --git a/CoreFoundation/URL.subproj/CFURLSessionInterface.h b/CoreFoundation/URL.subproj/CFURLSessionInterface.h
index 6655ea8..6dc29bc 100644
--- a/CoreFoundation/URL.subproj/CFURLSessionInterface.h
+++ b/CoreFoundation/URL.subproj/CFURLSessionInterface.h
@@ -546,11 +546,11 @@
 CF_EXPORT int const CFURLSessionSeekCantSeek;
 CF_EXPORT int const CFURLSessionSeekFail;
 
-CF_EXPORT CFURLSessionEasyHandle _Nonnull CFURLSessionEasyHandleInit();
+CF_EXPORT CFURLSessionEasyHandle _Nonnull CFURLSessionEasyHandleInit(void);
 CF_EXPORT void CFURLSessionEasyHandleDeinit(CFURLSessionEasyHandle _Nonnull handle);
 CF_EXPORT CFURLSessionEasyCode CFURLSessionEasyHandleSetPauseState(CFURLSessionEasyHandle _Nonnull handle, int send, int receive);
 
-CF_EXPORT CFURLSessionMultiHandle _Nonnull CFURLSessionMultiHandleInit();
+CF_EXPORT CFURLSessionMultiHandle _Nonnull CFURLSessionMultiHandleInit(void);
 CF_EXPORT CFURLSessionMultiCode CFURLSessionMultiHandleDeinit(CFURLSessionMultiHandle _Nonnull handle);
 CF_EXPORT CFURLSessionMultiCode CFURLSessionMultiHandleAddHandle(CFURLSessionMultiHandle _Nonnull handle, CFURLSessionEasyHandle _Nonnull curl);
 CF_EXPORT CFURLSessionMultiCode CFURLSessionMultiHandleRemoveHandle(CFURLSessionMultiHandle _Nonnull handle, CFURLSessionEasyHandle _Nonnull curl);
diff --git a/Docs/Status.md b/Docs/Status.md
index 13c9cfd..fa06c03 100644
--- a/Docs/Status.md
+++ b/Docs/Status.md
@@ -278,7 +278,7 @@
     | `Process`        | Mostly Complete | Substantial   | `interrupt()`, `terminate()`, `suspend()`, and `resume()` remain unimplemented                                            |
     | `Bundle`         | Mostly Complete | Incomplete    | `allBundles`, `init(for:)`, `unload()`, `classNamed()`, and `principalClass` remain unimplemented                         |
     | `ProcessInfo`    | Complete        | Substantial   |                                                                                                                           |
-    | `Thread`         | Incomplete      | Incomplete    | `isMainThread`, `mainThread`, `name`, `callStackReturnAddresses`, and `callStackSymbols` remain unimplemented             |
+    | `Thread`         | Complete        | Incomplete    |                                                                                                                           |
     | `Operation`      | Complete        | Incomplete    |                                                                                                                           |
     | `BlockOperation` | Complete        | Incomplete    |                                                                                                                           |
     | `OperationQueue` | Complete        | Incomplete    |                                                                                                                           |
diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index 6c21d09..eeace9e 100644
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -14,12 +14,14 @@
 		231503DB1D8AEE5D0061694D /* TestDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestDecimal.swift */; };
 		294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
 		2EBE67A51C77BF0E006583D5 /* TestDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestDateFormatter.swift */; };
+		3E55A2331F52463B00082000 /* TestUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E55A2321F52463B00082000 /* TestUnit.swift */; };
 		3EA9D6701EF0532D00B362D6 /* TestJSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */; };
 		3EDCE50C1EF04D8100C2EC04 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCE5051EF04D8100C2EC04 /* Codable.swift */; };
 		3EDCE5101EF04D8100C2EC04 /* JSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCE5091EF04D8100C2EC04 /* JSONEncoder.swift */; };
 		528776141BF2629700CB0090 /* FoundationErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522C253A1BF16E1600804FC6 /* FoundationErrors.swift */; };
 		528776191BF27D9500CB0090 /* Test.plist in Resources */ = {isa = PBXBuildFile; fileRef = 528776181BF27D9500CB0090 /* Test.plist */; };
 		555683BD1C1250E70041D4C6 /* TestUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 555683BC1C1250E70041D4C6 /* TestUserDefaults.swift */; };
+		559451EC1F706BFA002807FB /* CFXMLPreferencesDomain.c in Sources */ = {isa = PBXBuildFile; fileRef = 559451EA1F706BF5002807FB /* CFXMLPreferencesDomain.c */; };
 		5B0163BB1D024EB7003CCD96 /* DateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0163BA1D024EB7003CCD96 /* DateComponents.swift */; };
 		5B13B3251C582D4700651CE2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA66F6381BF1619600136161 /* main.swift */; };
 		5B13B3261C582D4C00651CE2 /* TestAffineTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93559281C12C49F009FD6A9 /* TestAffineTransform.swift */; };
@@ -308,6 +310,7 @@
 		61E011821C1B599A000037DD /* CFMachPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D01BBC9AAC00234F36 /* CFMachPort.c */; };
 		63DCE9D21EAA430100E9CB02 /* ISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */; };
 		63DCE9D41EAA432400E9CB02 /* TestISO8601DateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */; };
+		684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684C79001F62B611005BD73E /* TestNSNumberBridging.swift */; };
 		6EB768281D18C12C00D4B719 /* UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB768271D18C12C00D4B719 /* UUID.swift */; };
 		7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */; };
 		7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7900433A1CACD33E00ECCBF1 /* TestNSPredicate.swift */; };
@@ -490,6 +493,7 @@
 		231503DA1D8AEE5D0061694D /* TestDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDecimal.swift; sourceTree = "<group>"; };
 		294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
 		2EBE67A31C77BF05006583D5 /* TestDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDateFormatter.swift; sourceTree = "<group>"; };
+		3E55A2321F52463B00082000 /* TestUnit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestUnit.swift; sourceTree = "<group>"; };
 		3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestJSONEncoder.swift; sourceTree = "<group>"; };
 		3EDCE5051EF04D8100C2EC04 /* Codable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Codable.swift; sourceTree = "<group>"; };
 		3EDCE5091EF04D8100C2EC04 /* JSONEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONEncoder.swift; sourceTree = "<group>"; };
@@ -501,6 +505,7 @@
 		52829AD61C160D64003BC4EF /* TestCalendar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCalendar.swift; sourceTree = "<group>"; };
 		528776181BF27D9500CB0090 /* Test.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Test.plist; sourceTree = "<group>"; };
 		555683BC1C1250E70041D4C6 /* TestUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUserDefaults.swift; sourceTree = "<group>"; usesTabs = 1; };
+		559451EA1F706BF5002807FB /* CFXMLPreferencesDomain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFXMLPreferencesDomain.c; sourceTree = "<group>"; };
 		5B0163BA1D024EB7003CCD96 /* DateComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateComponents.swift; sourceTree = "<group>"; };
 		5B0C6C211C1E07E600705A0E /* TestNSRegularExpression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSRegularExpression.swift; sourceTree = "<group>"; };
 		5B1FD9C11D6D160F0080E83C /* CFURLSessionInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLSessionInterface.c; sourceTree = "<group>"; };
@@ -765,6 +770,7 @@
 		61F8AE7C1C180FC600FB62F0 /* TestNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNotificationCenter.swift; sourceTree = "<group>"; };
 		63DCE9D11EAA430100E9CB02 /* ISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ISO8601DateFormatter.swift; sourceTree = "<group>"; };
 		63DCE9D31EAA432400E9CB02 /* TestISO8601DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestISO8601DateFormatter.swift; sourceTree = "<group>"; };
+		684C79001F62B611005BD73E /* TestNSNumberBridging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSNumberBridging.swift; sourceTree = "<group>"; };
 		6E203B8C1C1303BB003B2576 /* TestBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; };
 		6EB768271D18C12C00D4B719 /* UUID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UUID.swift; sourceTree = "<group>"; };
 		790043391CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSCompoundPredicate.swift; sourceTree = "<group>"; };
@@ -1030,6 +1036,7 @@
 			isa = PBXGroup;
 			children = (
 				5B5D886A1BBC948300234F36 /* CFApplicationPreferences.c */,
+				559451EA1F706BF5002807FB /* CFXMLPreferencesDomain.c */,
 				5B5D898B1BBDBF6500234F36 /* CFPreferences.c */,
 				5B5D886C1BBC94C400234F36 /* CFPreferences.h */,
 			);
@@ -1457,6 +1464,7 @@
 				5EF673AB1C28B527006212A3 /* TestNotificationQueue.swift */,
 				5B6F17921C48631C00935030 /* TestNSNull.swift */,
 				EA66F63F1BF1619600136161 /* TestNSNumber.swift */,
+				684C79001F62B611005BD73E /* TestNSNumberBridging.swift */,
 				D5C40F321CDA1D460005690C /* TestOperationQueue.swift */,
 				D834F9931C31C4060023812A /* TestNSOrderedSet.swift */,
 				BDFDF0A61DFF5B3E00C04CC5 /* TestPersonNameComponents.swift */,
@@ -1494,6 +1502,7 @@
 				D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
 				5B6F17961C48631C00935030 /* TestUtils.swift */,
 				03B6F5831F15F339004F25AF /* TestURLProtocol.swift */,
+				3E55A2321F52463B00082000 /* TestUnit.swift */,
 			);
 			name = Tests;
 			sourceTree = "<group>";
@@ -2021,7 +2030,7 @@
 				TargetAttributes = {
 					5B5D885C1BBC938800234F36 = {
 						CreatedOnToolsVersion = 7.1;
-						LastSwiftMigration = 0800;
+						LastSwiftMigration = 0900;
 						LastSwiftUpdateCheck = 0800;
 						ProvisioningStyle = Manual;
 					};
@@ -2300,6 +2309,7 @@
 				5B7C8A8B1BEA7FE200C5B690 /* CFBigNumber.c in Sources */,
 				5B7C8A7D1BEA7FCE00C5B690 /* CFBinaryHeap.c in Sources */,
 				5B7C8A7E1BEA7FCE00C5B690 /* CFBitVector.c in Sources */,
+				559451EC1F706BFA002807FB /* CFXMLPreferencesDomain.c in Sources */,
 				5B7C8A8F1BEA7FEC00C5B690 /* CFBinaryPList.c in Sources */,
 				5B7C8A911BEA7FEC00C5B690 /* CFPropertyList.c in Sources */,
 				5B7C8AB41BEA801700C5B690 /* CFStringEncodingDatabase.c in Sources */,
@@ -2419,6 +2429,7 @@
 				F9E0BB371CA70B8000F7FF3C /* TestURLCredential.swift in Sources */,
 				5B13B3341C582D4C00651CE2 /* TestNSKeyedArchiver.swift in Sources */,
 				5B13B3441C582D4C00651CE2 /* TestNSSet.swift in Sources */,
+				3E55A2331F52463B00082000 /* TestUnit.swift in Sources */,
 				5B13B3321C582D4C00651CE2 /* TestIndexSet.swift in Sources */,
 				5B13B3511C582D4C00651CE2 /* TestByteCountFormatter.swift in Sources */,
 				BDFDF0A71DFF5B3E00C04CC5 /* TestPersonNameComponents.swift in Sources */,
@@ -2433,6 +2444,7 @@
 				3EA9D6701EF0532D00B362D6 /* TestJSONEncoder.swift in Sources */,
 				D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */,
 				D4FE895B1D703D1100DA7986 /* TestURLRequest.swift in Sources */,
+				684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */,
 				5B13B33A1C582D4C00651CE2 /* TestNSNumber.swift in Sources */,
 				5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
 				5B13B3311C582D4C00651CE2 /* TestIndexPath.swift in Sources */,
@@ -2686,6 +2698,7 @@
 				OTHER_LDFLAGS = (
 					"-twolevel_namespace",
 					"-Wl,-alias_list,CoreFoundation/Base.subproj/SymbolAliases",
+					"-Wl,-all_load",
 					"-sectcreate",
 					__UNICODE,
 					__csbitmaps,
diff --git a/Foundation/AffineTransform.swift b/Foundation/AffineTransform.swift
index cfd0504..3f1923f 100644
--- a/Foundation/AffineTransform.swift
+++ b/Foundation/AffineTransform.swift
@@ -338,6 +338,10 @@
         return other === self
             || (other.transformStruct == self.transformStruct)
     }
+
+    open override var hashValue: Int {
+        return transformStruct.hashValue
+    }
     
     public static var supportsSecureCoding: Bool {
         return true
diff --git a/Foundation/Bundle.swift b/Foundation/Bundle.swift
index b0814fb..5c66d37 100644
--- a/Foundation/Bundle.swift
+++ b/Foundation/Bundle.swift
@@ -77,7 +77,8 @@
     open var isLoaded: Bool {
         return CFBundleIsExecutableLoaded(_bundle)
     }
-    open func unload() -> Bool { NSUnimplemented() }
+    @available(*,deprecated,message:"Not available on non-Darwin platforms")
+    open func unload() -> Bool { NSUnsupported() }
     
     open func preflight() throws {
         var unmanagedError:Unmanaged<CFError>? = nil
diff --git a/Foundation/ByteCountFormatter.swift b/Foundation/ByteCountFormatter.swift
index e268880..3234e4e 100644
--- a/Foundation/ByteCountFormatter.swift
+++ b/Foundation/ByteCountFormatter.swift
@@ -13,8 +13,6 @@
         public let rawValue : UInt
         public init(rawValue: UInt) { self.rawValue = rawValue }
         
-        // This causes default units appropriate for the platform to be used. Specifying any units explicitly causes just those units to be used in showing the number.
-        public static let useDefault = Units(rawValue: 0)
         //  Specifying any of the following causes the specified units to be used in showing the number.
         public static let useBytes = Units(rawValue: 1 << 0)
         public static let useKB = Units(rawValue: 1 << 1)
@@ -50,9 +48,9 @@
         NSUnimplemented()
     }
     
-    /* Specify the units that can be used in the output. If ByteCountFormatter.Units.useDefault, uses platform-appropriate settings; otherwise will only use the specified units. This is the default value. Note that ZB and YB cannot be covered by the range of possible values, but you can still choose to use these units to get fractional display ("0.0035 ZB" for instance).
+    /* Specify the units that can be used in the output. If ByteCountFormatter.Units is empty, uses platform-appropriate settings; otherwise will only use the specified units. This is the default value. Note that ZB and YB cannot be covered by the range of possible values, but you can still choose to use these units to get fractional display ("0.0035 ZB" for instance).
      */
-    open var allowedUnits: Units = .useDefault
+    open var allowedUnits: Units = []
     
     /* Specify how the count is displayed by indicating the number of bytes to be used for kilobyte. The default setting is ByteCountFormatter.CountStyle.fileCount, which is the system specific value for file and storage sizes.
      */
@@ -127,52 +125,52 @@
      */
     private func convertValue(fromByteCount byteCount: Int64, for byteSize: [Unit: Double]) -> String {
         let byte = Double(byteCount)
-        if byte == 0, allowsNonnumericFormatting, allowedUnits == .useDefault, includesUnit, includesCount {
+        if byte == 0, allowsNonnumericFormatting, allowedUnits == [], includesUnit, includesCount {
             return partsToIncludeFor(value: "Zero", unit: Unit.KB)
         } else if byte == 1 || byte == -1 {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return formatNumberFor(bytes: byte, unit: Unit.byte)
             } else {
                 return valueToUseFor(byteCount: byte, unit: allowedUnits)
             }
         } else if  byte < byteSize[Unit.KB]! && byte > -byteSize[Unit.KB]!{
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return formatNumberFor(bytes: byte, unit: Unit.bytes)
             } else {
                 return valueToUseFor(byteCount: byte, unit: allowedUnits)
             }
         } else if byte < byteSize[Unit.MB]! && byte > -byteSize[Unit.MB]! {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .KB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
             
         } else if byte < byteSize[Unit.GB]! && byte > -byteSize[Unit.GB]! {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .MB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
             
         } else if byte < byteSize[Unit.TB]! && byte > -byteSize[Unit.TB]! {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .GB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
             
         } else if byte < byteSize[Unit.PB]! && byte > -byteSize[Unit.PB]! {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .TB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
             
         } else if byte < byteSize[Unit.EB]! && byte > -byteSize[Unit.EB]! {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .PB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
             
         } else {
-            if allowedUnits.contains(.useAll) || allowedUnits == .useDefault {
+            if allowedUnits.contains(.useAll) || allowedUnits == [] {
                 return divide(byte, by: byteSize, for: .EB)
             }
             return valueToUseFor(byteCount: byte, unit: allowedUnits)
@@ -297,7 +295,7 @@
             } else {
                 if lengthOfInt(number: Int(bytes)) == 3 {
                     numberFormatter.usesSignificantDigits = false
-                    numberFormatter.maximumFractionDigits = 1
+                    numberFormatter.maximumFractionDigits = 0
                 } else {
                     numberFormatter.maximumSignificantDigits = 3
                     numberFormatter.minimumSignificantDigits = 3
@@ -376,7 +374,7 @@
         } else if includesCount, includesUnit {
             return "\(value) \(unit)"
         } else if includesCount, !includesUnit {
-            if value == "Zero", allowedUnits == .useDefault {
+            if value == "Zero", allowedUnits == [] {
                 return "0"
             } else {
                 return value
diff --git a/Foundation/Data.swift b/Foundation/Data.swift
index aa63929..5398567 100644
--- a/Foundation/Data.swift
+++ b/Foundation/Data.swift
@@ -27,6 +27,10 @@
 internal func __NSDataInvokeDeallocatorFree(_ mem: UnsafeMutableRawPointer, _ length: Int) {
     free(mem)
 }
+
+internal func __NSDataIsCompact(_ data: NSData) -> Bool {
+    return data._isCompact()
+}
     
 #else
     
@@ -98,47 +102,140 @@
     public var _needToZero: Bool
     public var _deallocator: ((UnsafeMutableRawPointer, Int) -> Void)?
     public var _backing: Backing = .swift
+    public var _offset: Int
     
     public var bytes: UnsafeRawPointer? {
         @inline(__always)
         get {
             switch _backing {
             case .swift:
-                return UnsafeRawPointer(_bytes)
+                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
             case .immutable:
-                return UnsafeRawPointer(_bytes)
+                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
             case .mutable:
-                return UnsafeRawPointer(_bytes)
+                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
             case .customReference(let d):
-                return d.bytes
+                return d.bytes.advanced(by: -_offset)
             case .customMutableReference(let d):
-                return d.bytes
+                return d.bytes.advanced(by: -_offset)
+            }
+        }
+    }
+
+    @discardableResult
+    public func withUnsafeBytes<Result>(in range: Range<Int>, apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
+        switch _backing {
+        case .swift: fallthrough
+        case .immutable: fallthrough
+        case .mutable:
+            return try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, _length)))
+        case .customReference(let d):
+            if d._isCompact() {
+                let len = d.length
+                guard len > 0 else {
+                    return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
+                }
+                return try apply(UnsafeRawBufferPointer(start: d.bytes.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, len)))
+            } else {
+                var buffer = UnsafeMutableRawBufferPointer.allocate(count: range.count)
+                defer { buffer.deallocate() }
+                let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
+                var enumerated = 0
+                d.enumerateBytes { (ptr, byteRange, stop) in
+                    if NSIntersectionRange(sliceRange, byteRange).length > 0 {
+                        let lower = Swift.max(byteRange.location, sliceRange.location)
+                        let upper = Swift.min(byteRange.location + byteRange.length, sliceRange.location + sliceRange.length)
+                        let offset = lower - byteRange.location
+                        let effectiveRange = NSRange(location: lower, length: upper - lower)
+                        if effectiveRange == sliceRange {
+                            memcpy(buffer.baseAddress!, ptr, effectiveRange.length)
+                            stop.pointee = true
+                        } else {
+                            memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
+                        }
+                        enumerated += byteRange.length
+                    } else if sliceRange.location + sliceRange.length < byteRange.location {
+                        stop.pointee = true
+                    }
+                }
+                return try apply(UnsafeRawBufferPointer(buffer))
+            }
+        case .customMutableReference(let d):
+            if d._isCompact() {
+                let len = d.length
+                guard len > 0 else {
+                    return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
+                }
+                return try apply(UnsafeRawBufferPointer(start: d.bytes.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, len)))
+            } else {
+                var buffer = UnsafeMutableRawBufferPointer.allocate(count: range.count)
+                defer { buffer.deallocate() }
+                let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
+                var enumerated = 0
+                d.enumerateBytes { (ptr, byteRange, stop) in
+                    if NSIntersectionRange(sliceRange, byteRange).length > 0 {
+                        let lower = Swift.max(byteRange.location, sliceRange.location)
+                        let upper = Swift.min(byteRange.location + byteRange.length, sliceRange.location + sliceRange.length)
+                        let effectiveRange = NSRange(location: lower, length: upper - lower)
+                        if effectiveRange == sliceRange {
+                            memcpy(buffer.baseAddress!, ptr, effectiveRange.length)
+                            stop.pointee = true
+                        } else {
+                            memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr, effectiveRange.length)
+                        }
+                        enumerated += byteRange.length
+                    } else if sliceRange.location + sliceRange.length < byteRange.location {
+                        stop.pointee = true
+                    }
+                }
+                return try apply(UnsafeRawBufferPointer(buffer))
             }
         }
     }
     
+    @discardableResult
+    public func withUnsafeMutableBytes<Result>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
+        switch _backing {
+        case .swift: fallthrough
+        case .mutable:
+            return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length - range.lowerBound)))
+        case .customMutableReference(let d):
+            let len = d.length
+            return try apply(UnsafeMutableRawBufferPointer(start: d.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len - range.lowerBound)))
+        case .immutable(let d):
+            let data = d.mutableCopy() as! NSMutableData
+            _backing = .mutable(data)
+            _bytes = data.mutableBytes
+            return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length - range.lowerBound)))
+        case .customReference(let d):
+            let data = d.mutableCopy() as! NSMutableData
+            _backing = .customMutableReference(data)
+            let len = data.length
+            return try apply(UnsafeMutableRawBufferPointer(start: data.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len - range.lowerBound)))
+        }
+    }
+
     public var mutableBytes: UnsafeMutableRawPointer? {
         @inline(__always)
         get {
             switch _backing {
             case .swift:
-                return _bytes
+                return _bytes?.advanced(by: -_offset)
             case .immutable(let d):
                 let data = d.mutableCopy() as! NSMutableData
                 data.length = length
                 _backing = .mutable(data)
                 _bytes = data.mutableBytes
-                return data.mutableBytes
+                return _bytes?.advanced(by: -_offset)
             case .mutable:
-                return _bytes
+                return _bytes?.advanced(by: -_offset)
             case .customReference(let d):
                 let data = d.mutableCopy() as! NSMutableData
                 data.length = length
                 _backing = .customMutableReference(data)
-                _bytes = data.mutableBytes
-                return data.mutableBytes
+                return data.mutableBytes.advanced(by: -_offset)
             case .customMutableReference(let d):
-                return d.mutableBytes
+                return d.mutableBytes.advanced(by: -_offset)
             }
         }
     }
@@ -176,32 +273,34 @@
         }
     }
     
-    public func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Data.Index, _ stop: inout Bool) -> Void) {
-        var stop: Bool = false
+    public func enumerateBytes(in range: Range<Int>, _ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Data.Index, _ stop: inout Bool) -> Void) {
+        var stopv: Bool = false
+        var data: NSData
         switch _backing {
-        case .swift:
-            block(UnsafeBufferPointer<UInt8>(start: _bytes?.assumingMemoryBound(to: UInt8.self), count: _length), 0, &stop)
-        case .immutable:
-            block(UnsafeBufferPointer<UInt8>(start: _bytes?.assumingMemoryBound(to: UInt8.self), count: _length), 0, &stop)
-        case .mutable:
-            block(UnsafeBufferPointer<UInt8>(start: _bytes?.assumingMemoryBound(to: UInt8.self), count: _length), 0, &stop)
+        case .swift: fallthrough
+        case .immutable: fallthrough
+        case .mutable: 
+            block(UnsafeBufferPointer<UInt8>(start: _bytes?.advanced(by: range.lowerBound - _offset).assumingMemoryBound(to: UInt8.self), count: Swift.min(range.count, _length)), 0, &stopv)
+            return
         case .customReference(let d):
-            d.enumerateBytes { (ptr, range, stop) in
-                var stopv = false
-                let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: range.length)
-                block(UnsafeBufferPointer(start: bytePtr, count: range.length), range.location, &stopv)
-                if stopv {
-                    stop.pointee = true
-                }
-            }
+            data = d
+            break
         case .customMutableReference(let d):
-            d.enumerateBytes { (ptr, range, stop) in
-                var stopv = false
-                let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: range.length)
-                block(UnsafeBufferPointer(start: bytePtr, count: range.length), range.location, &stopv)
-                if stopv {
-                    stop.pointee = true
-                }
+            data = d
+            break
+        }
+        data.enumerateBytes { (ptr, region, stop) in
+            // any region that is not in the range should be skipped
+            guard range.contains(region.lowerBound) || range.contains(region.upperBound) else { return }
+            var regionAdjustment = 0
+            if region.lowerBound < range.lowerBound {
+                regionAdjustment = range.lowerBound - (region.lowerBound - _offset)
+            }
+            let bytePtr  = ptr.advanced(by: regionAdjustment).assumingMemoryBound(to: UInt8.self)
+            let effectiveLength = Swift.min((region.location - _offset) + region.length, range.upperBound) - (region.location - _offset)
+            block(UnsafeBufferPointer(start: bytePtr, count: effectiveLength - regionAdjustment), region.location + regionAdjustment - _offset, &stopv)
+            if stopv {
+                stop.pointee = true
             }
         }
     }
@@ -319,7 +418,7 @@
     
     @inline(__always)
     public func append(_ bytes: UnsafeRawPointer, length: Int) {
-        precondition(length >= 0, "Length of appending bytes must be positive")
+        precondition(length >= 0, "Length of appending bytes must not be negative")
         switch _backing {
         case .swift:
             let origLength = _length
@@ -398,6 +497,43 @@
         }
         
     }
+
+    public func get(_ index: Int) -> UInt8 {
+        switch _backing {
+        case .swift: fallthrough
+        case .immutable: fallthrough
+        case .mutable:
+            return _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
+        case .customReference(let d):
+            if d._isCompact() {
+                return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
+            } else {
+                var byte: UInt8 = 0
+                d.enumerateBytes { (ptr, range, stop) in
+                    if NSLocationInRange(index, range) {
+                        let offset = index - range.location - _offset
+                        byte = ptr.advanced(by: offset).assumingMemoryBound(to: UInt8.self).pointee
+                        stop.pointee = true
+                    }
+                }
+                return byte
+            }
+        case .customMutableReference(let d):
+            if d._isCompact() {
+                return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
+            } else {
+                var byte: UInt8 = 0
+                d.enumerateBytes { (ptr, range, stop) in
+                    if NSLocationInRange(index, range) {
+                        let offset = index - range.location - _offset
+                        byte = ptr.advanced(by: offset).assumingMemoryBound(to: UInt8.self).pointee
+                        stop.pointee = true
+                    }
+                }
+                return byte
+            }
+        }
+    }
     
     @inline(__always)
     public func set(_ index: Int, to value: UInt8) {
@@ -405,7 +541,7 @@
         case .swift:
             fallthrough
         case .mutable:
-            _bytes!.advanced(by: index).assumingMemoryBound(to: UInt8.self).pointee = value
+            _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee = value
         default:
             var theByte = value
             let range = NSRange(location: index, length: 1)
@@ -427,28 +563,29 @@
                 }
                 _length = newLength
             }
-            _DataStorage.move(_bytes!.advanced(by: range.location), bytes!, range.length)
+            _DataStorage.move(_bytes!.advanced(by: range.location - _offset), bytes!, range.length)
         case .immutable(let d):
             let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: range, withBytes: bytes!)
+            data.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
             _backing = .mutable(data)
             _length = data.length
             _bytes = data.mutableBytes
         case .mutable(let d):
-            d.replaceBytes(in: range, withBytes: bytes!)
+            d.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
             _length = d.length
             _bytes = d.mutableBytes
         case .customReference(let d):
             let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: range, withBytes: bytes!)
+            data.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
-            d.replaceBytes(in: range, withBytes: bytes!)
+            d.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
         }
     }
     
     @inline(__always)
-    public func replaceBytes(in range: NSRange, with replacementBytes: UnsafeRawPointer?, length replacementLength: Int) {
+    public func replaceBytes(in range_: NSRange, with replacementBytes: UnsafeRawPointer?, length replacementLength: Int) {
+        let range = NSRange(location: range_.location - _offset, length: range_.length)
         let currentLength = _length
         let resultingLength = currentLength - range.length + replacementLength
         switch _backing {
@@ -480,12 +617,12 @@
             let data = d.mutableCopy() as! NSMutableData
             data.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
             _backing = .mutable(data)
-            _length = replacementLength
+            _length = data.length
             _bytes = data.mutableBytes
         case .mutable(let d):
             d.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
             _backing = .mutable(d)
-            _length = replacementLength
+            _length = d.length
             _bytes = d.mutableBytes
         case .customReference(let d):
             let data = d.mutableCopy() as! NSMutableData
@@ -497,7 +634,8 @@
     }
     
     @inline(__always)
-    public func resetBytes(in range: NSRange) {
+    public func resetBytes(in range_: NSRange) {
+        let range = NSRange(location: range_.location - _offset, length: range_.length)
         if range.length == 0 { return }
         switch _backing {
         case .swift:
@@ -546,6 +684,7 @@
         _capacity = capacity
         _needToZero = !clear
         _length = 0
+        _offset = 0
         setLength(length)
     }
     
@@ -560,10 +699,12 @@
         _bytes = _DataStorage.allocate(capacity, false)!
         _capacity = capacity
         _needToZero = true
+        _offset = 0
     }
     
     public init(bytes: UnsafeRawPointer?, length: Int) {
         precondition(length < _DataStorage.maxSize)
+        _offset = 0
         if length == 0 {
             _capacity = 0
             _length = 0
@@ -588,8 +729,9 @@
         }
     }
     
-    public init(bytes: UnsafeMutableRawPointer?, length: Int, copy: Bool, deallocator: ((UnsafeMutableRawPointer, Int) -> Void)?) {
+    public init(bytes: UnsafeMutableRawPointer?, length: Int, copy: Bool, deallocator: ((UnsafeMutableRawPointer, Int) -> Void)?, offset: Int) {
         precondition(length < _DataStorage.maxSize)
+        _offset = offset
         if length == 0 {
             _capacity = 0
             _length = 0
@@ -630,7 +772,8 @@
         }
     }
     
-    public init(immutableReference: NSData) {
+    public init(immutableReference: NSData, offset: Int) {
+        _offset = offset
         _bytes = UnsafeMutableRawPointer(mutating: immutableReference.bytes)
         _capacity = 0
         _needToZero = false
@@ -638,7 +781,8 @@
         _backing = .immutable(immutableReference)
     }
     
-    public init(mutableReference: NSMutableData) {
+    public init(mutableReference: NSMutableData, offset: Int) {
+        _offset = offset
         _bytes = mutableReference.mutableBytes
         _capacity = 0
         _needToZero = false
@@ -646,7 +790,8 @@
         _backing = .mutable(mutableReference)
     }
     
-    public init(customReference: NSData) {
+    public init(customReference: NSData, offset: Int) {
+        _offset = offset
         _bytes = nil
         _capacity = 0
         _needToZero = false
@@ -654,7 +799,8 @@
         _backing = .customReference(customReference)
     }
     
-    public init(customMutableReference: NSMutableData) {
+    public init(customMutableReference: NSMutableData, offset: Int) {
+        _offset = offset
         _bytes = nil
         _capacity = 0
         _needToZero = false
@@ -675,30 +821,30 @@
     public func mutableCopy(_ range: Range<Int>) -> _DataStorage {
         switch _backing {
         case .swift:
-            return _DataStorage(bytes: _bytes?.advanced(by: range.lowerBound), length: range.count, copy: true, deallocator: nil)
+            return _DataStorage(bytes: _bytes?.advanced(by: range.lowerBound - _offset), length: range.count, copy: true, deallocator: nil, offset: range.lowerBound)
         case .immutable(let d):
             if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
             } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
             }
         case .mutable(let d):
             if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
             } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
             }
         case .customReference(let d):
             if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
             } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
             }
         case .customMutableReference(let d):
             if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
             } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData)
+                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
             }
         }
     }
@@ -710,26 +856,26 @@
         
         switch _backing {
         case .swift:
-            return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound), length: range.count, freeWhenDone: false))
+            return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
         case .immutable(let d):
             guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound), length: range.count, freeWhenDone: false))
+                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
             }
             return try work(d)
         case .mutable(let d):
             guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound), length: range.count, freeWhenDone: false))
+                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
             }
             return try work(d)
         case .customReference(let d):
             guard range.lowerBound == 0 && range.upperBound == _length else {
                 
-                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound)), length: range.count, freeWhenDone: false))
+                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound - _offset)), length: range.count, freeWhenDone: false))
             }
             return try work(d)
         case .customMutableReference(let d):
             guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound)), length: range.count, freeWhenDone: false))
+                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound - _offset)), length: range.count, freeWhenDone: false))
             }
             return try work(d)
         }
@@ -766,26 +912,14 @@
         }
     }
     
-    public var hashValue: Int {
-        switch _backing {
-        case .customReference(let d):
-            return d.hash
-        case .customMutableReference(let d):
-            return d.hash
-        default:
-            let len = _length
-            return Int(bitPattern: CFHashBytes(_bytes?.assumingMemoryBound(to: UInt8.self), Swift.min(len, 80)))
-        }
-    }
-    
     public func subdata(in range: Range<Data.Index>) -> Data {
         switch _backing {
         case .customReference(let d):
-            return d.subdata(with: NSRange(location: range.lowerBound, length: range.count))
+            return d.subdata(with: NSRange(location: range.lowerBound - _offset, length: range.count))
         case .customMutableReference(let d):
-            return d.subdata(with: NSRange(location: range.lowerBound, length: range.count))
+            return d.subdata(with: NSRange(location: range.lowerBound - _offset, length: range.count))
         default:
-            return Data(bytes: _bytes!.advanced(by: range.lowerBound), count: range.count)
+            return Data(bytes: _bytes!.advanced(by: range.lowerBound - _offset), count: range.count)
         }
     }
 }
@@ -827,7 +961,7 @@
     }
     
 #if !DEPLOYMENT_RUNTIME_SWIFT
-    @objc
+    @objc override
     func _isCompact() -> Bool {
         return true
     }
@@ -1015,7 +1149,7 @@
     /// - parameter deallocator: Specifies the mechanism to free the indicated buffer, or `.none`.
     public init(bytesNoCopy bytes: UnsafeMutableRawPointer, count: Int, deallocator: Deallocator) {
         let whichDeallocator = deallocator._deallocator
-        _backing = _DataStorage(bytes: bytes, length: count, copy: false, deallocator: whichDeallocator)
+        _backing = _DataStorage(bytes: bytes, length: count, copy: false, deallocator: whichDeallocator, offset: 0)
         _sliceRange = 0..<count
     }
     
@@ -1026,7 +1160,7 @@
     /// - throws: An error in the Cocoa domain, if `url` cannot be read.
     public init(contentsOf url: URL, options: Data.ReadingOptions = []) throws {
         let d = try NSData(contentsOf: url, options: ReadingOptions(rawValue: options.rawValue))
-        _backing = _DataStorage(immutableReference: d)
+        _backing = _DataStorage(immutableReference: d, offset: 0)
         _sliceRange = 0..<d.length
     }
     
@@ -1037,7 +1171,7 @@
     /// - parameter options: Encoding options. Default value is `[]`.
     public init?(base64Encoded base64String: String, options: Data.Base64DecodingOptions = []) {
         if let d = NSData(base64Encoded: base64String, options: Base64DecodingOptions(rawValue: options.rawValue)) {
-            _backing = _DataStorage(immutableReference: d)
+            _backing = _DataStorage(immutableReference: d, offset: 0)
             _sliceRange = 0..<d.length
         } else {
             return nil
@@ -1052,7 +1186,7 @@
     /// - parameter options: Decoding options. Default value is `[]`.
     public init?(base64Encoded base64Data: Data, options: Data.Base64DecodingOptions = []) {
         if let d = NSData(base64Encoded: base64Data, options: Base64DecodingOptions(rawValue: options.rawValue)) {
-            _backing = _DataStorage(immutableReference: d)
+            _backing = _DataStorage(immutableReference: d, offset: 0)
             _sliceRange = 0..<d.length
         } else {
             return nil
@@ -1073,10 +1207,10 @@
         let providesConcreteBacking = (reference as AnyObject)._providesConcreteBacking?() ?? false
 #endif
         if providesConcreteBacking {
-            _backing = _DataStorage(immutableReference: reference.copy() as! NSData)
+            _backing = _DataStorage(immutableReference: reference.copy() as! NSData, offset: 0)
             _sliceRange = 0..<reference.length
         } else {
-            _backing = _DataStorage(customReference: reference.copy() as! NSData)
+            _backing = _DataStorage(customReference: reference.copy() as! NSData, offset: 0)
             _sliceRange = 0..<reference.length
         }
         
@@ -1085,40 +1219,30 @@
     // slightly faster paths for common sequences
     
     public init<S: Sequence>(_ elements: S) where S.Iterator.Element == UInt8 {
-        let underestimatedCount = elements.underestimatedCount
-        self.init(count: underestimatedCount)
-        var idx = 0
-        for byte in elements {
-            if idx < underestimatedCount {
-                self[idx] = byte
-            } else {
-                self.append(byte)
+        if elements is Array<UInt8> {
+            self.init(bytes: _identityCast(elements, to: Array<UInt8>.self))
+        } else if elements is ArraySlice<UInt8> {
+            self.init(bytes: _identityCast(elements, to: ArraySlice<UInt8>.self))
+        } else if elements is UnsafeBufferPointer<UInt8> {
+            self.init(buffer: _identityCast(elements, to: UnsafeBufferPointer<UInt8>.self))
+        } else if let buffer = elements as? UnsafeMutableBufferPointer<UInt8> {
+            self.init(buffer: buffer)
+        } else if let data = elements as? Data {
+            let len = data.count
+            let backing = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in
+                return _DataStorage(bytes: bytes, length: len)
             }
-            idx += 1
+            self.init(backing: backing, range: 0..<len)
+        } else {
+            let underestimatedCount = elements.underestimatedCount
+            self.init(count: underestimatedCount)
+            
+            let (endIterator, _) = UnsafeMutableBufferPointer(start: _backing._bytes?.assumingMemoryBound(to: UInt8.self), count: underestimatedCount).initialize(from: elements)
+            var iter = endIterator
+            while let byte = iter.next() { self.append(byte) }
         }
     }
-    
-    public init(_ bytes: Array<UInt8>) {
-        self.init(bytes: bytes)
-    }
-    
-    public init(_ bytes: ArraySlice<UInt8>) {
-        self.init(bytes: bytes)
-    }
-    
-    public init(_ buffer: UnsafeBufferPointer<UInt8>) {
-        self.init(buffer: buffer)
-    }
-    
-    public init(_ buffer: UnsafeMutableBufferPointer<UInt8>) {
-        self.init(buffer: buffer)
-    }
-    
-    public init(_ data: Data) {
-        _sliceRange = 0..<data.count
-        _backing = data._backing.mutableCopy(data._sliceRange)
-    }
-    
+
     @_versioned
     internal init(backing: _DataStorage, range: Range<Index>) {
         _backing = backing
@@ -1151,7 +1275,7 @@
         }
         @inline(__always)
         set {
-            precondition(count >= 0, "count must be positive")
+            precondition(count >= 0, "count must not be negative")
             if !isKnownUniquelyReferenced(&_backing) {
                 _backing = _backing.mutableCopy(_sliceRange)
             }
@@ -1165,9 +1289,9 @@
     /// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
     @inline(__always)
     public func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
-        let bytes =  _backing.bytes?.advanced(by: _sliceRange.lowerBound) ?? UnsafeRawPointer(bitPattern: 0xBAD0)!
-        let contentPtr = bytes.bindMemory(to: ContentType.self, capacity: count / MemoryLayout<ContentType>.stride)
-        return try body(contentPtr)
+        return try _backing.withUnsafeBytes(in: _sliceRange) {
+            return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafePointer<ContentType>(bitPattern: 0xBAD0)!)
+        }
     }
     
     
@@ -1180,9 +1304,9 @@
         if !isKnownUniquelyReferenced(&_backing) {
             _backing = _backing.mutableCopy(_sliceRange)
         }
-        let mutableBytes = _backing.mutableBytes?.advanced(by: _sliceRange.lowerBound) ?? UnsafeMutableRawPointer(bitPattern: 0xBAD0)!
-        let contentPtr = mutableBytes.bindMemory(to: ContentType.self, capacity: count / MemoryLayout<ContentType>.stride)
-        return try body(UnsafeMutablePointer(contentPtr))
+        return try _backing.withUnsafeMutableBytes(in: _sliceRange) {
+            return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafeMutablePointer<ContentType>(bitPattern: 0xBAD0)!)
+        }
     }
     
     // MARK: -
@@ -1195,15 +1319,19 @@
     /// - warning: This method does not verify that the contents at pointer have enough space to hold `count` bytes.
     @inline(__always)
     public func copyBytes(to pointer: UnsafeMutablePointer<UInt8>, count: Int) {
-        precondition(count >= 0, "count of bytes to copy must be positive")
+        precondition(count >= 0, "count of bytes to copy must not be negative")
         if count == 0 { return }
-        memcpy(UnsafeMutableRawPointer(pointer), _backing.bytes!.advanced(by: _sliceRange.lowerBound), Swift.min(count, _sliceRange.count))
+        _backing.withUnsafeBytes(in: _sliceRange) {
+            memcpy(UnsafeMutableRawPointer(pointer), $0.baseAddress!, Swift.min(count, $0.count))
+        }
     }
     
     @inline(__always)
     private func _copyBytesHelper(to pointer: UnsafeMutableRawPointer, from range: NSRange) {
         if range.length == 0 { return }
-        memcpy(UnsafeMutableRawPointer(pointer), _backing.bytes!.advanced(by: range.location), Swift.min(range.length, _sliceRange.count))
+        _backing.withUnsafeBytes(in: range.lowerBound..<range.upperBound) {
+            memcpy(UnsafeMutableRawPointer(pointer), $0.baseAddress!, Swift.min(range.length, $0.count))
+        }
     }
     
     /// Copy a subset of the contents of the data to a pointer.
@@ -1311,27 +1439,20 @@
     /// In some cases, (for example, a `Data` backed by a `dispatch_data_t`, the bytes may be stored discontiguously. In those cases, this function invokes the closure for each contiguous region of bytes.
     /// - parameter block: The closure to invoke for each region of data. You may stop the enumeration by setting the `stop` parameter to `true`.
     public func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
-        _backing.enumerateBytes(block)
+        _backing.enumerateBytes(in: _sliceRange, block)
     }
     
     @inline(__always)
     public mutating func append(_ bytes: UnsafePointer<UInt8>, count: Int) {
-        precondition(count >= 0, "count must be positive")
         if count == 0 { return }
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        _backing.append(bytes, length: count)
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.upperBound + count)
+        append(UnsafeBufferPointer(start: bytes, count: count))
     }
     
     @inline(__always)
     public mutating func append(_ other: Data) {
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
+        other.enumerateBytes { (buffer, _, _) in
+            append(buffer)
         }
-        _backing.append(other._backing, startingAt: other._sliceRange.lowerBound, endingAt: other._sliceRange.upperBound)
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.upperBound + other.count)
     }
     
     /// Append a buffer of bytes to the data.
@@ -1343,22 +1464,26 @@
         if !isKnownUniquelyReferenced(&_backing) {
             _backing = _backing.mutableCopy(_sliceRange)
         }
-        _backing.append(buffer.baseAddress!, length: buffer.count * MemoryLayout<SourceType>.stride)
+        _backing.replaceBytes(in: NSRange(location: _sliceRange.upperBound, length: _backing.length - (_sliceRange.upperBound - _backing._offset)), with: buffer.baseAddress, length: buffer.count * MemoryLayout<SourceType>.stride)
         _sliceRange = _sliceRange.lowerBound..<(_sliceRange.upperBound + buffer.count * MemoryLayout<SourceType>.stride)
     }
     
     @inline(__always)
     public mutating func append<S : Sequence>(contentsOf newElements: S) where S.Iterator.Element == Iterator.Element {
         let estimatedCount = newElements.underestimatedCount
-        var idx = count
-        count += estimatedCount
-        for byte in newElements {
-            let newIndex = idx + 1
-            if newIndex > count {
-                count = newIndex
+        guard estimatedCount > 0 else {
+            for byte in newElements {
+                append(byte)
             }
-            self[idx] = byte
-            idx = newIndex
+            return
+        }
+        _withStackOrHeapBuffer(estimatedCount) { allocation in
+            let buffer = UnsafeMutableBufferPointer(start: allocation.pointee.memory.assumingMemoryBound(to: UInt8.self), count: estimatedCount)
+            var (iterator, endPoint) = newElements._copyContents(initializing: buffer)
+            append(buffer.baseAddress!, count: endPoint - buffer.startIndex)
+            while let byte = iterator.next() {
+                append(byte)
+            }
         }
     }
     
@@ -1378,16 +1503,15 @@
     @inline(__always)
     public mutating func resetBytes(in range: Range<Index>) {
         // it is worth noting that the range here may be out of bounds of the Data itself (which triggers a growth)
-        precondition(range.lowerBound >= 0, "Ranges must be positive bounds")
-        precondition(range.upperBound >= 0, "Ranges must be positive bounds")
+        precondition(range.lowerBound >= 0, "Ranges must not be negative bounds")
+        precondition(range.upperBound >= 0, "Ranges must not be negative bounds")
         let range = NSMakeRange(range.lowerBound, range.upperBound - range.lowerBound)
         if !isKnownUniquelyReferenced(&_backing) {
             _backing = _backing.mutableCopy(_sliceRange)
         }
         _backing.resetBytes(in: range)
-        if _sliceRange.count < range.location + range.length {
-            let newLength = range.location + range.length
-            _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + newLength)
+        if _sliceRange.upperBound < range.upperBound {
+            _sliceRange = _sliceRange.lowerBound..<range.upperBound
         }
     }
     
@@ -1400,34 +1524,16 @@
     /// - parameter data: The replacement data.
     @inline(__always)
     public mutating func replaceSubrange(_ subrange: Range<Index>, with data: Data) {
-        _validateRange(subrange)
-        let nsRange = NSMakeRange(subrange.lowerBound, subrange.upperBound - subrange.lowerBound)
         let cnt = data.count
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
+        data.withUnsafeBytes {
+            replaceSubrange(subrange, with: $0, count: cnt)
         }
-        let resultingLength = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Int in
-            let currentLength = _backing.length
-            _backing.replaceBytes(in: nsRange, with: bytes, length: cnt)
-            return currentLength - nsRange.length + cnt
-        }
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + resultingLength)
     }
     
     @inline(__always)
     public mutating func replaceSubrange(_ subrange: CountableRange<Index>, with data: Data) {
-        _validateRange(subrange)
-        let nsRange = NSMakeRange(subrange.lowerBound, subrange.upperBound - subrange.lowerBound)
-        let cnt = data.count
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        let resultingLength = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Int in
-            let currentLength = _backing.length
-            _backing.replaceBytes(in: nsRange, with: bytes, length: cnt)
-            return currentLength - nsRange.length + cnt
-        }
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + resultingLength)
+        let range: Range<Int> = subrange.lowerBound..<subrange.upperBound
+        replaceSubrange(range, with: data)
     }
     
     /// Replace a region of bytes in the data with new bytes from a buffer.
@@ -1439,17 +1545,8 @@
     /// - parameter buffer: The replacement bytes.
     @inline(__always)
     public mutating func replaceSubrange<SourceType>(_ subrange: Range<Index>, with buffer: UnsafeBufferPointer<SourceType>) {
-        _validateRange(subrange)
-        let nsRange = NSMakeRange(subrange.lowerBound, subrange.upperBound - subrange.lowerBound)
-        let bufferCount = buffer.count * MemoryLayout<SourceType>.stride
-        
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        let currentLength = _backing.length
-        _backing.replaceBytes(in: nsRange, with: buffer.baseAddress, length: bufferCount)
-        let resultingLength = currentLength - nsRange.length + bufferCount
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + resultingLength)
+        guard buffer.count > 0  else { return }
+        replaceSubrange(subrange, with: buffer.baseAddress!, count: buffer.count * MemoryLayout<SourceType>.stride)
     }
     
     /// Replace a region of bytes in the data with new bytes from a collection.
@@ -1460,39 +1557,18 @@
     /// - parameter subrange: The range in the data to replace.
     /// - parameter newElements: The replacement bytes.
     @inline(__always)
-    public mutating func replaceSubrange<ByteCollection : Collection>(_ subrange: Range<Index>, with newElements: ByteCollection)
-        where ByteCollection.Iterator.Element == Data.Iterator.Element {
-            _validateRange(subrange)
-            // Calculate this once, it may not be O(1)
-            let replacementCount: Int = numericCast(newElements.count)
-            let currentCount = self.count
-            let subrangeCount = subrange.count
-            
-            _validateRange(subrange)
-            
-            let resultCount = currentCount - subrangeCount + replacementCount
-            if resultCount != currentCount {
-                // This may realloc.
-                // In the future, if we keep the malloced pointer and count inside this struct/ref instead of deferring to NSData, we may be able to do this more efficiently.
-                self.count = resultCount
+    public mutating func replaceSubrange<ByteCollection : Collection>(_ subrange: Range<Index>, with newElements: ByteCollection) where ByteCollection.Iterator.Element == Data.Iterator.Element {
+        _validateRange(subrange)
+        let totalCount: Int = numericCast(newElements.count)
+        _withStackOrHeapBuffer(totalCount) { conditionalBuffer in
+            let buffer = UnsafeMutableBufferPointer(start: conditionalBuffer.pointee.memory.assumingMemoryBound(to: UInt8.self), count: totalCount)
+            var (iterator, index) = newElements._copyContents(initializing: buffer)
+            while let byte = iterator.next() {
+                buffer[index] = byte
+                index = buffer.index(after: index)
             }
-            
-            let shift = resultCount - currentCount
-            let start = subrange.lowerBound
-            
-            self.withUnsafeMutableBytes { (bytes : UnsafeMutablePointer<UInt8>) -> Void in
-                if shift != 0 {
-                    let destination = bytes + start + replacementCount
-                    let source = bytes + start + subrangeCount
-                    memmove(destination, source, currentCount - start - subrangeCount)
-                }
-                
-                if replacementCount != 0 {
-                    let buf = UnsafeMutableBufferPointer(start: bytes + start, count: replacementCount)
-                    var (it,idx) = newElements._copyContents(initializing: buf)
-                    precondition(it.next() == nil && idx == buf.endIndex, "newElements iterator returned different count to newElements.count")
-                }
-            }
+            replaceSubrange(subrange, with: conditionalBuffer.pointee.memory, count: totalCount)
+        }
     }
     
     @inline(__always)
@@ -1502,10 +1578,10 @@
         if !isKnownUniquelyReferenced(&_backing) {
             _backing = _backing.mutableCopy(_sliceRange)
         }
-        let currentLength = _backing.length
+        let upper = _sliceRange.upperBound
         _backing.replaceBytes(in: nsRange, with: bytes, length: cnt)
-        let resultingLength = currentLength - nsRange.length + cnt
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + resultingLength)
+        let resultingUpper = upper - nsRange.length + cnt
+        _sliceRange = _sliceRange.lowerBound..<resultingUpper
     }
     
     /// Return a new copy of the data in a specified range.
@@ -1514,6 +1590,7 @@
     @inline(__always)
     public func subdata(in range: Range<Index>) -> Data {
         _validateRange(range)
+        let length = count
         if count == 0 {
             return Data()
         }
@@ -1548,7 +1625,15 @@
     
     /// The hash value for the data.
     public var hashValue: Int {
-        return _backing.hashValue
+        var hashValue = 0
+        let hashRange: Range<Int> = _sliceRange.lowerBound..<Swift.min(_sliceRange.lowerBound + 80, _sliceRange.upperBound)
+        _withStackOrHeapBuffer(hashRange.count) { buffer in
+            _backing.withUnsafeBytes(in: hashRange) {
+                memcpy(buffer.pointee.memory, $0.baseAddress!, hashRange.count)
+            }
+            hashValue = Int(bitPattern: CFHashBytes(buffer.pointee.memory.assumingMemoryBound(to: UInt8.self), hashRange.count))
+        }
+        return hashValue
     }
     
     @inline(__always)
@@ -1571,7 +1656,7 @@
         @inline(__always)
         get {
             _validateIndex(index)
-            return _backing.bytes!.advanced(by: index).assumingMemoryBound(to: UInt8.self).pointee
+            return _backing.get(index)
         }
         @inline(__always)
         set {
@@ -1657,11 +1742,24 @@
         }
     }
     
+    public func _copyContents(initializing buffer: UnsafeMutableBufferPointer<UInt8>) -> (Iterator, UnsafeMutableBufferPointer<UInt8>.Index) {
+        guard !isEmpty else { return (makeIterator(), buffer.startIndex) }
+        guard let p = buffer.baseAddress else {
+            preconditionFailure("Attempt to copy contents into nil buffer pointer")
+        }
+        let cnt = count
+        precondition(cnt <= buffer.count, "Insufficient space allocated to copy Data contents")
+        
+        withUnsafeBytes { p.initialize(from: $0, count: cnt) }
+        
+        return (Iterator(endOf: self), buffer.index(buffer.startIndex, offsetBy: cnt))
+    }
+    
     /// An iterator over the contents of the data.
     ///
     /// The iterator will increment byte-by-byte.
     public func makeIterator() -> Data.Iterator {
-        return Iterator(_data: self)
+        return Iterator(self)
     }
     
     public struct Iterator : IteratorProtocol {
@@ -1674,11 +1772,18 @@
         private var _idx: Data.Index
         private let _endIdx: Data.Index
         
-        fileprivate init(_data: Data) {
-            self._data = _data
+        fileprivate init(_ data: Data) {
+            _data = data
             _buffer = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
-            _idx = _data.startIndex
-            _endIdx = _data.endIndex
+            _idx = data.startIndex
+            _endIdx = data.endIndex
+        }
+        
+        fileprivate init(endOf data: Data) {
+            self._data = data
+            _buffer = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
+            _idx = data.endIndex
+            _endIdx = data.endIndex
         }
         
         public mutating func next() -> UInt8? {
@@ -1764,7 +1869,7 @@
         
         // Minimal size data is output as an array
         if nBytes < 64 {
-            children.append((label: "bytes", value: Array(self[0..<nBytes])))
+            children.append((label: "bytes", value: Array(self[startIndex..<Swift.min(nBytes + startIndex, endIndex)])))
         }
         
         let m = Mirror(self, children:children, displayStyle: Mirror.DisplayStyle.struct)
@@ -1821,11 +1926,27 @@
 
 extension Data : Codable {
     public init(from decoder: Decoder) throws {
+        // FIXME: This is a hook for bypassing a conditional conformance implementation to apply a strategy (see SR-5206). Remove this once conditional conformance is available.
+        do {
+            let singleValueContainer = try decoder.singleValueContainer()
+            if let decoder = singleValueContainer as? _JSONDecoder {
+                switch decoder.options.dataDecodingStrategy {
+                case .deferredToData:
+                    break /* fall back to default implementation below; this would recurse */
+
+                default:
+                    // _JSONDecoder has a hook for Datas; this won't recurse since we're not going to defer back to Data in _JSONDecoder.
+                    self = try singleValueContainer.decode(Data.self)
+                    return
+                }
+            }
+        } catch { /* fall back to default implementation below */ }
+
         var container = try decoder.unkeyedContainer()
         
         // It's more efficient to pre-allocate the buffer if we can.
         if let count = container.count {
-            self.init(count: count)
+            self = Data(count: count)
             
             // Loop only until count, not while !container.isAtEnd, in case count is underestimated (this is misbehavior) and we haven't allocated enough space.
             // We don't want to write past the end of what we allocated.
@@ -1834,7 +1955,7 @@
                 self[i] = byte
             }
         } else {
-            self.init()
+            self = Data()
         }
         
         while !container.isAtEnd {
@@ -1844,6 +1965,21 @@
     }
     
     public func encode(to encoder: Encoder) throws {
+        // FIXME: This is a hook for bypassing a conditional conformance implementation to apply a strategy (see SR-5206). Remove this once conditional conformance is available.
+        // We are allowed to request this container as long as we don't encode anything through it when we need the unkeyed container below.
+        var singleValueContainer = encoder.singleValueContainer()
+        if let encoder = singleValueContainer as? _JSONEncoder {
+            switch encoder.options.dataEncodingStrategy {
+            case .deferredToData:
+                break /* fall back to default implementation below; this would recurse */
+
+            default:
+                // _JSONEncoder has a hook for Datas; this won't recurse since we're not going to defer back to Data in _JSONEncoder.
+                try singleValueContainer.encode(self)
+                return
+            }
+        }
+
         var container = encoder.unkeyedContainer()
         
         // Since enumerateBytes does not rethrow, we need to catch the error, stow it away, and rethrow if we stopped.
@@ -1862,4 +1998,3 @@
         }
     }
 }
-
diff --git a/Foundation/DateFormatter.swift b/Foundation/DateFormatter.swift
index 184b861..31292a0 100644
--- a/Foundation/DateFormatter.swift
+++ b/Foundation/DateFormatter.swift
@@ -142,9 +142,23 @@
         }
     }
 
-    open var dateStyle: Style = .none { willSet { _dateFormat = nil; _reset() } }
+    open var dateStyle: Style = .none {
+        willSet {
+            _dateFormat = nil
+        }
+        didSet {
+            _dateFormat = CFDateFormatterGetFormat(_cfObject)._swiftObject
+        }
+    }
 
-    open var timeStyle: Style = .none { willSet { _dateFormat = nil; _reset() } }
+    open var timeStyle: Style = .none {
+        willSet {
+            _dateFormat = nil
+        }
+        didSet {
+            _dateFormat = CFDateFormatterGetFormat(_cfObject)._swiftObject
+        }
+    }
 
     /*@NSCopying*/ open var locale: Locale! = .current { willSet { _reset() } }
 
diff --git a/Foundation/Decimal.swift b/Foundation/Decimal.swift
index 3174ca4..36417b1 100644
--- a/Foundation/Decimal.swift
+++ b/Foundation/Decimal.swift
@@ -327,6 +327,7 @@
     }
 
     public mutating func negate() {
+        guard _length != 0 else { return }
         _isNegative = _isNegative == 0 ? 1 : 0
     }
 }
@@ -1282,9 +1283,7 @@
 
 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()
-    }
+    r.negate()
     return NSDecimalAdd(result, leftOperand, &r, roundingMode)
 }
 // Exact operations. result may be a pointer to same space as leftOperand or rightOperand
diff --git a/Foundation/ExtraStringAPIs.swift b/Foundation/ExtraStringAPIs.swift
index 2f5d4f1..6085c22 100644
--- a/Foundation/ExtraStringAPIs.swift
+++ b/Foundation/ExtraStringAPIs.swift
@@ -13,19 +13,9 @@
 // Random access for String.UTF16View, only when Foundation is
 // imported.  Making this API dependent on Foundation decouples the
 // Swift core from a UTF16 representation.
-extension String.UTF16View.Index : Strideable {
-    /// Construct from an integer offset.
-    public init(_ offset: Int) {
-        _precondition(offset >= 0, "Negative UTF16 index offset not allowed")
-        self.init(encodedOffset: offset)
-    }
-    
-    public func distance(to other: String.UTF16View.Index) -> Int {
-        return encodedOffset.distance(to: other.encodedOffset)
-    }
-    
+extension String.UTF16View.Index {
     public func advanced(by n: Int) -> String.UTF16View.Index {
-        return String.UTF16View.Index(encodedOffset.advanced(by: n))
+        return String.UTF16View.Index(encodedOffset: encodedOffset.advanced(by: n))
     }
 }
 
diff --git a/Foundation/FileHandle.swift b/Foundation/FileHandle.swift
index 28bf722..2f31d44 100644
--- a/Foundation/FileHandle.swift
+++ b/Foundation/FileHandle.swift
@@ -103,13 +103,16 @@
             dynamicBuffer = _CFReallocf(dynamicBuffer!, total)
         }
         
-        if (0 == total) {
+        if total == 0 {
             free(dynamicBuffer)
         }
-        
-        if total > 0 {
+        else if total > 0 {
             let bytePtr = dynamicBuffer!.bindMemory(to: UInt8.self, capacity: total)
-            return Data(bytesNoCopy: bytePtr, count: total, deallocator: .none)
+            return Data(bytesNoCopy: bytePtr, count: total, deallocator: .free)
+        }
+        else {
+            assertionFailure("The total number of read bytes must not be negative")
+            free(dynamicBuffer)
         }
         
         return Data()
diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift
index f7ca2e1..e5e2673 100644
--- a/Foundation/FileManager.swift
+++ b/Foundation/FileManager.swift
@@ -158,7 +158,7 @@
                 } else if let attr = attributes {
                     try self.setAttributes(attr, ofItemAtPath: path)
                 }
-            } else if isDir {
+            } else if isDir.boolValue {
                 return
             } else {
                 throw _NSErrorWithErrno(EEXIST, reading: false, path: path)
@@ -406,9 +406,9 @@
     }
     
     open func linkItem(atPath srcPath: String, toPath dstPath: String) throws {
-        var isDir = false
+        var isDir: ObjCBool = false
         if self.fileExists(atPath: srcPath, isDirectory: &isDir) {
-            if !isDir {
+            if !isDir.boolValue {
                 // TODO: Symlinks should be copied instead of hard-linked.
                 if link(srcPath, dstPath) == -1 {
                     throw _NSErrorWithErrno(errno, reading: false, path: srcPath)
@@ -532,12 +532,13 @@
             if let isDirectory = isDirectory {
                 if (s.st_mode & S_IFMT) == S_IFLNK {
                     if stat(path, &s) >= 0 {
-                        isDirectory.pointee = (s.st_mode & S_IFMT) == S_IFDIR
+                        isDirectory.pointee = ObjCBool((s.st_mode & S_IFMT) == S_IFDIR)
                     } else {
                         return false
                     }
                 } else {
-                    isDirectory.pointee = (s.st_mode & S_IFMT) == S_IFDIR
+                    let isDir = (s.st_mode & S_IFMT) == S_IFDIR
+                    isDirectory.pointee = ObjCBool(isDir)
                 }
             }
 
@@ -718,7 +719,11 @@
     open var homeDirectoryForCurrentUser: URL {
         return homeDirectory(forUser: CFCopyUserName().takeRetainedValue()._swiftObject)!
     }
-    open var temporaryDirectory: URL { NSUnimplemented() }
+    
+    open var temporaryDirectory: URL {
+        return URL(fileURLWithPath: NSTemporaryDirectory())
+    }
+    
     open func homeDirectory(forUser userName: String) -> URL? {
         guard !userName.isEmpty else { return nil }
         guard let url = CFCopyHomeDirectoryURLForUser(userName._cfObject) else { return nil }
diff --git a/Foundation/HTTPCookie.swift b/Foundation/HTTPCookie.swift
index 2fc9fbc..fcd284c 100644
--- a/Foundation/HTTPCookie.swift
+++ b/Foundation/HTTPCookie.swift
@@ -249,7 +249,7 @@
         _domain = canonicalDomain
 
         if let
-            secureString = properties[.secure] as? String, !secureString.characters.isEmpty
+            secureString = properties[.secure] as? String, !secureString.isEmpty
         {
             _secure = true
         } else {
@@ -267,8 +267,7 @@
         _version = version
 
         if let portString = properties[.port] as? String, _version == 1 {
-            _portList = portString.characters
-                .split(separator: ",")
+            _portList = portString.split(separator: ",")
                 .flatMap { Int(String($0)) }
                 .map { NSNumber(value: $0) }
         } else {
@@ -361,8 +360,8 @@
         }
         //Remove the final trailing semicolon and whitespace
         if ( cookieString.length > 0 ) {
-            cookieString.characters.removeLast()
-            cookieString.characters.removeLast()
+            cookieString.removeLast()
+            cookieString.removeLast()
         }
         return ["Cookie": cookieString]
     }
@@ -624,7 +623,7 @@
     }
 
     func insertComma(at index:Int) -> String {
-        return  String(self.characters.prefix(index)) + ","  + String(self.characters.suffix(self.characters.count-index))
+        return  String(self.prefix(index)) + ","  + String(self.suffix(self.count-index))
     }
 }
 
diff --git a/Foundation/HTTPCookieStorage.swift b/Foundation/HTTPCookieStorage.swift
index 2e9e080..2209818 100644
--- a/Foundation/HTTPCookieStorage.swift
+++ b/Foundation/HTTPCookieStorage.swift
@@ -36,20 +36,40 @@
 */
 open class HTTPCookieStorage: NSObject {
 
+    /* both sharedStorage and sharedCookieStorages are synchronized on sharedSyncQ */
     private static var sharedStorage: HTTPCookieStorage?
     private static var sharedCookieStorages: [String: HTTPCookieStorage] = [:] //for group storage containers
+    private static let sharedSyncQ = DispatchQueue(label: "org.swift.HTTPCookieStorage.sharedSyncQ")
+
+    /* only modified in init */
     private var cookieFilePath: String!
-    private let workQueue: DispatchQueue = DispatchQueue(label: "HTTPCookieStorage.workqueue")
-    var allCookies: [String: HTTPCookie]
+
+    /* synchronized on syncQ, please don't use _allCookies directly outside of init/deinit */
+    private var _allCookies: [String: HTTPCookie]
+    private var allCookies: [String: HTTPCookie] {
+        get {
+            if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+                dispatchPrecondition(condition: DispatchPredicate.onQueue(self.syncQ))
+            }
+            return self._allCookies
+        }
+        set {
+            if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+                dispatchPrecondition(condition: DispatchPredicate.onQueue(self.syncQ))
+            }
+            self._allCookies = newValue
+        }
+    }
+    private let syncQ = DispatchQueue(label: "org.swift.HTTPCookieStorage.syncQ")
 
     private init(cookieStorageName: String) {
-        allCookies = [:]
+        _allCookies = [:]
         cookieAcceptPolicy = .always
         super.init()
         let bundlePath = Bundle.main.bundlePath
         var bundleName = bundlePath.components(separatedBy: "/").last!
         if let range = bundleName.range(of: ".", options: String.CompareOptions.backwards, range: nil, locale: nil) {
-            bundleName = bundleName.substring(to: range.lowerBound)
+            bundleName = String(bundleName[..<range.lowerBound])
         }
         let cookieFolderPath = _CFXDGCreateDataHomePath()._swiftObject + "/" + bundleName
         cookieFilePath = filePath(path: cookieFolderPath, fileName: "/.cookies." + cookieStorageName, bundleName: bundleName)
@@ -59,9 +79,11 @@
     private func loadPersistedCookies() {
         guard let cookies = NSMutableDictionary(contentsOfFile: cookieFilePath) else { return }
         var cookies0 = _SwiftValue.fetch(cookies) as? [String: [String: Any]] ?? [:]
-        for key in cookies0.keys {
-            if let cookie = createCookie(cookies0[key]!) {
-                allCookies[key] = cookie
+        self.syncQ.sync {
+            for key in cookies0.keys {
+                if let cookie = createCookie(cookies0[key]!) {
+                    allCookies[key] = cookie
+                }
             }
         }
     }
@@ -87,11 +109,7 @@
     }
 
     open var cookies: [HTTPCookie]? {
-        var theCookies: [HTTPCookie]?
-        workQueue.sync {
-                theCookies = Array(self.allCookies.values)
-        }
-        return theCookies
+        return Array(self.syncQ.sync { self.allCookies.values })
     }
     
     /*!
@@ -103,10 +121,12 @@
     */
     open class var shared: HTTPCookieStorage {
         get {
-            if sharedStorage == nil {
-                sharedStorage = HTTPCookieStorage(cookieStorageName: "shared")
+            return sharedSyncQ.sync {
+                if sharedStorage == nil {
+                    sharedStorage = HTTPCookieStorage(cookieStorageName: "shared")
+                }
+                return sharedStorage!
             }
-            return sharedStorage!
         }
     }
     
@@ -122,12 +142,14 @@
         method with the same identifier will return the same cookie storage instance.
      */
     open class func sharedCookieStorage(forGroupContainerIdentifier identifier: String) -> HTTPCookieStorage {
-        guard let cookieStorage = sharedCookieStorages[identifier] else {
-            let newCookieStorage = HTTPCookieStorage(cookieStorageName: identifier)
-            sharedCookieStorages[identifier] = newCookieStorage
-            return newCookieStorage
+        return sharedSyncQ.sync {
+            guard let cookieStorage = sharedCookieStorages[identifier] else {
+                let newCookieStorage = HTTPCookieStorage(cookieStorageName: identifier)
+                sharedCookieStorages[identifier] = newCookieStorage
+                return newCookieStorage
+            }
+            return cookieStorage
         }
-        return cookieStorage
     }
 
     
@@ -138,7 +160,7 @@
         same name, domain and path, if any.
     */
     open func setCookie(_ cookie: HTTPCookie) {
-        workQueue.sync {
+        self.syncQ.sync {
             guard cookieAcceptPolicy != .never else { return }
 
             //add or override
@@ -173,9 +195,13 @@
     }
 
     private func updatePersistentStore() {
+        if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+            dispatchPrecondition(condition: DispatchPredicate.onQueue(self.syncQ))
+        }
+
         //persist cookies
         var persistDictionary: [String : [String : Any]] = [:]
-        let persistable = allCookies.filter { (_, value) in
+        let persistable = self.allCookies.filter { (_, value) in
             value.expiresDate != nil &&
             value.isSessionOnly == false &&
             value.expiresDate!.timeIntervalSinceNow > 0
@@ -190,14 +216,22 @@
     }
 
     /*!
+        @method lockedDeleteCookie:
+        @abstract Delete the specified cookie, for internal callers already on syncQ.
+    */
+    private func lockedDeleteCookie(_ cookie: HTTPCookie) {
+        let key = cookie.domain + cookie.path + cookie.name
+        self.allCookies.removeValue(forKey: key)
+        updatePersistentStore()
+    }
+
+    /*!
         @method deleteCookie:
         @abstract Delete the specified cookie
     */
     open func deleteCookie(_ cookie: HTTPCookie) {
-        let key = cookie.domain + cookie.path + cookie.name
-        workQueue.sync {
-            self.allCookies.removeValue(forKey: key)
-            updatePersistentStore()
+        self.syncQ.sync {
+            self.lockedDeleteCookie(cookie)
         }
     }
     
@@ -206,13 +240,15 @@
      @abstract Delete all cookies from the cookie storage since the provided date.
      */
     open func removeCookies(since date: Date) {
-        let cookiesSinceDate = allCookies.values.filter {
-            $0.properties![.created] as! Double >  date.timeIntervalSinceReferenceDate
+        self.syncQ.sync {
+            let cookiesSinceDate = self.allCookies.values.filter {
+                $0.properties![.created] as! Double >  date.timeIntervalSinceReferenceDate
+            }
+            for cookie in cookiesSinceDate {
+                lockedDeleteCookie(cookie)
+            }
+            updatePersistentStore()
         }
-        for cookie in cookiesSinceDate {
-            deleteCookie(cookie)
-        }
-        updatePersistentStore()
     }
 
     /*!
@@ -226,12 +262,8 @@
         into a set of header fields to add to a request.
     */
     open func cookies(for url: URL) -> [HTTPCookie]? {
-        var cookies: [HTTPCookie]?
         guard let host = url.host else { return nil }
-        workQueue.sync {
-            cookies = Array(allCookies.values.filter{ $0.domain == host })
-        }
-        return cookies
+        return Array(self.syncQ.sync(execute: {allCookies}).values.filter{ $0.domain == host })
     }
     
     /*!
diff --git a/Foundation/IndexSet.swift b/Foundation/IndexSet.swift
index ea103fa..1b4c7c4 100644
--- a/Foundation/IndexSet.swift
+++ b/Foundation/IndexSet.swift
@@ -407,7 +407,7 @@
     public func intersects(integersIn range: CountableClosedRange<Element>) -> Bool { return self.intersects(integersIn: Range(range)) }
     
     // MARK: -
-    // Indexable
+    // Collection
     
     public func index(after i: Index) -> Index {
         if i.value + 1 == i.extent.upperBound {
diff --git a/Foundation/JSONEncoder.swift b/Foundation/JSONEncoder.swift
index 59a3844..5c36e1f 100644
--- a/Foundation/JSONEncoder.swift
+++ b/Foundation/JSONEncoder.swift
@@ -64,8 +64,11 @@
 
     /// The strategy to use for encoding `Data` values.
     public enum DataEncodingStrategy {
+        /// Defer to `Data` for choosing an encoding.
+        case deferredToData
+        
         /// Encoded the `Data` as a Base64-encoded string. This is the default strategy.
-        case base64Encode
+        case base64
 
         /// Encode the `Data` as a custom value encoded by the given closure.
         ///
@@ -88,8 +91,8 @@
     /// The strategy to use in encoding dates. Defaults to `.deferredToDate`.
     open var dateEncodingStrategy: DateEncodingStrategy = .deferredToDate
 
-    /// The strategy to use in encoding binary data. Defaults to `.base64Encode`.
-    open var dataEncodingStrategy: DataEncodingStrategy = .base64Encode
+    /// The strategy to use in encoding binary data. Defaults to `.base64`.
+    open var dataEncodingStrategy: DataEncodingStrategy = .base64
 
     /// The strategy to use in encoding non-conforming numbers. Defaults to `.throw`.
     open var nonConformingFloatEncodingStrategy: NonConformingFloatEncodingStrategy = .throw
@@ -98,7 +101,7 @@
     open var userInfo: [CodingUserInfoKey : Any] = [:]
 
     /// Options set on the top-level encoder to pass down the encoding hierarchy.
-    fileprivate struct _Options {
+    internal struct _Options {
         let dateEncodingStrategy: DateEncodingStrategy
         let dataEncodingStrategy: DataEncodingStrategy
         let nonConformingFloatEncodingStrategy: NonConformingFloatEncodingStrategy
@@ -150,14 +153,14 @@
 
 // MARK: - _JSONEncoder
 
-fileprivate class _JSONEncoder : Encoder {
+internal class _JSONEncoder : Encoder {
     // MARK: Properties
 
     /// The encoder's storage.
     fileprivate var storage: _JSONEncodingStorage
 
     /// Options set on the top-level encoder.
-    fileprivate let options: JSONEncoder._Options
+    internal let options: JSONEncoder._Options
 
     /// The path to the current point in encoding.
     public var codingPath: [CodingKey]
@@ -672,7 +675,12 @@
 
     fileprivate func box(_ data: Data) throws -> NSObject {
         switch self.options.dataEncodingStrategy {
-        case .base64Encode:
+        case .deferredToData:
+            // Must be called with a surrounding with(pushedKey:) call.
+            try data.encode(to: self)
+            return self.storage.popContainer()
+            
+        case .base64:
             return NSString(string: data.base64EncodedString())
 
         case .custom(let closure):
@@ -826,8 +834,11 @@
 
     /// The strategy to use for decoding `Data` values.
     public enum DataDecodingStrategy {
+        /// Defer to `Data` for decoding.
+        case deferredToData
+        
         /// Decode the `Data` from a Base64-encoded string. This is the default strategy.
-        case base64Decode
+        case base64
 
         /// Decode the `Data` as a custom value decoded by the given closure.
         case custom((_ decoder: Decoder) throws -> Data)
@@ -845,8 +856,8 @@
     /// The strategy to use in decoding dates. Defaults to `.deferredToDate`.
     open var dateDecodingStrategy: DateDecodingStrategy = .deferredToDate
 
-    /// The strategy to use in decoding binary data. Defaults to `.base64Decode`.
-    open var dataDecodingStrategy: DataDecodingStrategy = .base64Decode
+    /// The strategy to use in decoding binary data. Defaults to `.base64`.
+    open var dataDecodingStrategy: DataDecodingStrategy = .base64
 
     /// The strategy to use in decoding non-conforming numbers. Defaults to `.throw`.
     open var nonConformingFloatDecodingStrategy: NonConformingFloatDecodingStrategy = .throw
@@ -855,7 +866,7 @@
     open var userInfo: [CodingUserInfoKey : Any] = [:]
 
     /// Options set on the top-level encoder to pass down the decoding hierarchy.
-    fileprivate struct _Options {
+    internal struct _Options {
         let dateDecodingStrategy: DateDecodingStrategy
         let dataDecodingStrategy: DataDecodingStrategy
         let nonConformingFloatDecodingStrategy: NonConformingFloatDecodingStrategy
@@ -893,14 +904,14 @@
 
 // MARK: - _JSONDecoder
 
-fileprivate class _JSONDecoder : Decoder {
+internal class _JSONDecoder : Decoder {
     // MARK: Properties
 
     /// The decoder's storage.
     fileprivate var storage: _JSONDecodingStorage
 
     /// Options set on the top-level decoder.
-    fileprivate let options: JSONDecoder._Options
+    internal let options: JSONDecoder._Options
 
     /// The path to the current point in encoding.
     private(set) public var codingPath: [CodingKey]
@@ -2042,7 +2053,13 @@
         guard !(value is NSNull) else { return nil }
 
         switch self.options.dataDecodingStrategy {
-        case .base64Decode:
+        case .deferredToData:
+            self.storage.push(container: value)
+            let data = try Data(from: self)
+            self.storage.popContainer()
+            return data
+            
+        case .base64:
             guard let string = value as? String else {
                 throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
             }
diff --git a/Foundation/JSONSerialization.swift b/Foundation/JSONSerialization.swift
index d03a528..c624e7a 100644
--- a/Foundation/JSONSerialization.swift
+++ b/Foundation/JSONSerialization.swift
@@ -62,8 +62,9 @@
                 return true
             }
             
-            // object is Swift.String, NSNull, Int, Bool, or UInt
-            if obj is String || obj is NSNull || obj is Int || obj is Bool || obj is UInt {
+            if obj is String || obj is NSNull || obj is Int || obj is Bool || obj is UInt ||
+                obj is Int8 || obj is Int16 || obj is Int32 || obj is Int64 ||
+                obj is UInt8 || obj is UInt16 || obj is UInt32 || obj is UInt64 {
                 return true
             }
 
@@ -76,6 +77,10 @@
                 return number.isFinite
             }
 
+            if let number = obj as? Decimal {
+                return number.isFinite
+            }
+
             // object is Swift.Array
             if let array = obj as? [Any?] {
                 for element in array {
@@ -99,8 +104,13 @@
             // object is NSNumber and is not NaN or infinity
             // For better performance, this (most expensive) test should be last.
             if let number = _SwiftValue.store(obj) as? NSNumber {
-                let invalid = number.doubleValue.isInfinite || number.doubleValue.isNaN
-                return !invalid
+                if CFNumberIsFloatType(number._cfObject) {
+                    let dv = number.doubleValue
+                    let invalid = dv.isInfinite || dv.isNaN
+                    return !invalid
+                } else {
+                    return true
+                }
             }
 
             // invalid object
@@ -139,13 +149,7 @@
         } else if let container = value as? Dictionary<AnyHashable, Any> {
             try writer.serializeJSON(container)
         } else {
-            if stream {
-                throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: [
-                    "NSDebugDescription" : "Top-level object was not NSArray or NSDictionary"
-                    ])
-            } else {
-                fatalError("Top-level object was not NSArray or NSDictionary") // This is a fatal error in objective-c too (it is an NSInvalidArgumentException)
-            }
+            fatalError("Top-level object was not NSArray or NSDictionary") // This is a fatal error in objective-c too (it is an NSInvalidArgumentException)
         }
         
         let count = jsonStr.lengthOfBytes(using: .utf8)
@@ -291,9 +295,7 @@
 
 //MARK: - JSONSerializer
 private struct JSONWriter {
-    
-    private let maxUIntLength = String(describing: UInt.max).characters.count
-    private let maxIntLength = String(describing: Int.max).characters.count
+
     var indent = 0
     let pretty: Bool
     let sortedKeys: Bool
@@ -326,13 +328,37 @@
         case let boolValue as Bool:
             serializeBool(boolValue)
         case let num as Int:
-            try serializeInt(value: num)
+            serializeInteger(value: num)
+        case let num as Int8:
+            serializeInteger(value: num)
+        case let num as Int16:
+            serializeInteger(value: num)
+        case let num as Int32:
+            serializeInteger(value: num)
+        case let num as Int64:
+            serializeInteger(value: num)
         case let num as UInt:
-            try serializeUInt(value: num)
+            serializeInteger(value: num)
+        case let num as UInt8:
+            serializeInteger(value: num)
+        case let num as UInt16:
+            serializeInteger(value: num)
+        case let num as UInt32:
+            serializeInteger(value: num)
+        case let num as UInt64:
+            serializeInteger(value: num)
         case let array as Array<Any?>:
             try serializeArray(array)
         case let dict as Dictionary<AnyHashable, Any?>:
             try serializeDictionary(dict)
+        case let num as Float:
+            try serializeNumber(NSNumber(value: num))
+        case let num as Double:
+            try serializeNumber(NSNumber(value: num))
+        case let num as Decimal:
+            writer(num.description)
+        case let num as NSDecimalNumber:
+            writer(num.description)
         case is NSNull:
             try serializeNull()
         case _ where _SwiftValue.store(obj) is NSNumber:
@@ -342,92 +368,33 @@
         }
     }
 
-    private func serializeUInt(value: UInt) throws {
-        if value == 0 {
-            writer("0")
-            return
-        }
-        var array: [UInt] = []
-        var stringResult = ""
-        //Maximum length of an UInt
-        array.reserveCapacity(maxUIntLength)
-        stringResult.reserveCapacity(maxUIntLength)
-        var number = value
-        
-        while number != 0 {
-            array.append(number % 10)
+    private func serializeInteger<T: UnsignedInteger>(value: T, isNegative: Bool = false) {
+        let maxIntLength = 22   // 20 digits in UInt64 + optional sign + trailing '\0'
+        let asciiZero: CChar = 0x30  // ASCII '0' == 0x30
+        let asciiMinus: CChar = 0x2d // ASCII '-' == 0x2d
+
+        var number = UInt64(value)
+        var buffer = Array<CChar>(repeating: 0, count: maxIntLength)
+        var pos = maxIntLength - 1
+
+        repeat {
+            pos -= 1
+            buffer[pos] = asciiZero + CChar(number % 10)
             number /= 10
+        } while number != 0
+
+        if isNegative {
+            pos -= 1
+            buffer[pos] = asciiMinus
         }
-        
-        /*
-         Step backwards through the array and append the values to the string. This way the values are appended in the correct order.
-         */
-        var counter = array.count
-        while counter > 0 {
-            counter -= 1
-            let digit: UInt = array[counter]
-            switch digit {
-            case 0: stringResult.append("0")
-            case 1: stringResult.append("1")
-            case 2: stringResult.append("2")
-            case 3: stringResult.append("3")
-            case 4: stringResult.append("4")
-            case 5: stringResult.append("5")
-            case 6: stringResult.append("6")
-            case 7: stringResult.append("7")
-            case 8: stringResult.append("8")
-            case 9: stringResult.append("9")
-            default: fatalError()
-            }
-        }
-        
-        writer(stringResult)
+        let output = String(cString: Array(buffer.suffix(from: pos)))
+        writer(output)
     }
-    
-    private func serializeInt(value: Int) throws {
-        if value == 0 {
-            writer("0")
-            return
-        }
-        var array: [Int] = []
-        var stringResult = ""
-        array.reserveCapacity(maxIntLength)
-        //Account for a negative sign
-        stringResult.reserveCapacity(maxIntLength + 1)
-        var number = value
-        
-        while number != 0 {
-            array.append(number % 10)
-            number /= 10
-        }
-        //If negative add minus sign before adding any values
-        if value < 0 {
-            stringResult.append("-")
-        }
-        /*
-         Step backwards through the array and append the values to the string. This way the values are appended in the correct order.
-         */
-        var counter = array.count
-        while counter > 0 {
-            counter -= 1
-            let digit = array[counter]
-            switch digit {
-            case 0: stringResult.append("0")
-            case 1, -1: stringResult.append("1")
-            case 2, -2: stringResult.append("2")
-            case 3, -3: stringResult.append("3")
-            case 4, -4: stringResult.append("4")
-            case 5, -5: stringResult.append("5")
-            case 6, -6: stringResult.append("6")
-            case 7, -7: stringResult.append("7")
-            case 8, -8: stringResult.append("8")
-            case 9, -9: stringResult.append("9")
-            default: fatalError()
-            }
-        }
-        writer(stringResult)
+
+    private func serializeInteger<T: SignedInteger>(value: T) {
+        serializeInteger(value: UInt64(value.magnitude), isNegative: value < 0)
     }
-    
+
     func serializeString(_ str: String) throws {
         writer("\"")
         for scalar in str.unicodeScalars {
@@ -468,15 +435,30 @@
     }
 
     mutating func serializeNumber(_ num: NSNumber) throws {
-        if num.doubleValue.isInfinite || num.doubleValue.isNaN {
-            throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Number cannot be infinity or NaN"])
-        }
-        
-        switch num._cfTypeID {
-        case CFBooleanGetTypeID():
-            serializeBool(num.boolValue)
-        default:
-            writer(_serializationString(for: num))
+        if CFNumberIsFloatType(num._cfObject) {
+            let dv = num.doubleValue
+            if !dv.isFinite {
+                let value: String
+                if dv.isNaN {
+                    value = "NaN"
+                } else if dv.isInfinite {
+                    value = "infinite"
+                } else {
+                    value = String(dv)
+                }
+
+                throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Invalid number value (\(value)) in JSON write"])
+            }
+
+            let string = CFNumberFormatterCreateStringWithNumber(nil, _numberformatter, num._cfObject)._swiftObject
+            writer(string)
+        } else {
+            switch num._cfTypeID {
+            case CFBooleanGetTypeID():
+                serializeBool(num.boolValue)
+            default:
+                writer(num.stringValue)
+            }
         }
     }
 
@@ -530,7 +512,7 @@
             } else {
                 throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "NSDictionary key must be NSString"])
             }
-            pretty ? writer(": ") : writer(":")
+            pretty ? writer(" : ") : writer(":")
             try serializeJSON(value)
         }
 
@@ -583,11 +565,7 @@
             writer(" ")
         }
     }
-    
-    //[SR-2151] https://bugs.swift.org/browse/SR-2151
-    private mutating func _serializationString(for number: NSNumber) -> String {
-        return CFNumberFormatterCreateStringWithNumber(nil, _numberformatter, number._cfObject)._swiftObject
-    }
+
 }
 
 //MARK: - JSONDeserializer
diff --git a/Foundation/Measurement.swift b/Foundation/Measurement.swift
index 99f6904..b119af1 100644
--- a/Foundation/Measurement.swift
+++ b/Foundation/Measurement.swift
@@ -275,3 +275,60 @@
         return Measurement(value: source!.doubleValue, unit: u)
     }
 }
+
+extension Measurement : Codable {
+    private enum CodingKeys : Int, CodingKey {
+        case value
+        case unit
+    }
+
+    private enum UnitCodingKeys : Int, CodingKey {
+        case symbol
+        case converter
+    }
+
+    private enum LinearConverterCodingKeys : Int, CodingKey {
+        case coefficient
+        case constant
+    }
+
+    public init(from decoder: Decoder) throws {
+        let container = try decoder.container(keyedBy: CodingKeys.self)
+        let value = try container.decode(Double.self, forKey: .value)
+
+        let unitContainer = try container.nestedContainer(keyedBy: UnitCodingKeys.self, forKey: .unit)
+        let symbol = try unitContainer.decode(String.self, forKey: .symbol)
+
+        let unit: UnitType
+        if UnitType.self is Dimension.Type {
+            let converterContainer = try unitContainer.nestedContainer(keyedBy: LinearConverterCodingKeys.self, forKey: .converter)
+            let coefficient = try converterContainer.decode(Double.self, forKey: .coefficient)
+            let constant = try converterContainer.decode(Double.self, forKey: .constant)
+            let unitMetaType = (UnitType.self as! Dimension.Type)
+            unit = (unitMetaType.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient, constant: constant)) as! UnitType)
+        } else {
+            unit = UnitType(symbol: symbol)
+        }
+
+        self.init(value: value, unit: unit)
+    }
+
+    public func encode(to encoder: Encoder) throws {
+        var container = encoder.container(keyedBy: CodingKeys.self)
+        try container.encode(self.value, forKey: .value)
+
+        var unitContainer = container.nestedContainer(keyedBy: UnitCodingKeys.self, forKey: .unit)
+        try unitContainer.encode(self.unit.symbol, forKey: .symbol)
+
+        if UnitType.self is Dimension.Type {
+            guard type(of: (self.unit as! Dimension).converter) is UnitConverterLinear.Type else {
+                preconditionFailure("Cannot encode a Measurement whose UnitType has a non-linear unit converter.")
+            }
+
+            let converter = (self.unit as! Dimension).converter as! UnitConverterLinear
+            var converterContainer = unitContainer.nestedContainer(keyedBy: LinearConverterCodingKeys.self, forKey: .converter)
+            try converterContainer.encode(converter.coefficient, forKey: .coefficient)
+            try converterContainer.encode(converter.constant, forKey: .constant)
+        }
+    }
+}
diff --git a/Foundation/NSAttributedString.swift b/Foundation/NSAttributedString.swift
index 17dbe92..3877813 100644
--- a/Foundation/NSAttributedString.swift
+++ b/Foundation/NSAttributedString.swift
@@ -115,7 +115,7 @@
                 attributesInRange = attributes(at: currentIndex, longestEffectiveRange: &attributesEffectiveRange, in: enumerationRange)
             }
             
-            var shouldStop = false
+            var shouldStop: ObjCBool = false
             block(attributesInRange, attributesEffectiveRange, &shouldStop)
             stop.pointee = shouldStop
             
@@ -133,7 +133,7 @@
                 attributeInRange = attribute(attrName, at: currentIndex, longestEffectiveRange: &attributeEffectiveRange, in: enumerationRange)
             }
             
-            var shouldStop = false
+            var shouldStop: ObjCBool = false
             block(attributeInRange, attributeEffectiveRange, &shouldStop)
             stop.pointee = shouldStop
             
@@ -232,10 +232,10 @@
     func _enumerate(in enumerationRange: NSRange, reversed: Bool, using block: (Int, UnsafeMutablePointer<ObjCBool>) -> NSRange) {
         var attributeEnumerationRange = AttributeEnumerationRange(range: enumerationRange, reversed: reversed)
         while attributeEnumerationRange.hasMore {
-            var stop = false
+            var stop: ObjCBool = false
             let effectiveRange = block(attributeEnumerationRange.currentIndex, &stop)
             attributeEnumerationRange.advance(step: effectiveRange.length)
-            if stop {
+            if stop.boolValue {
                 break
             }
         }
diff --git a/Foundation/NSData.swift b/Foundation/NSData.swift
index 6dd8048..3066406 100644
--- a/Foundation/NSData.swift
+++ b/Foundation/NSData.swift
@@ -146,6 +146,7 @@
     public convenience init(bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int, deallocator: ((UnsafeMutableRawPointer, Int) -> Void)? = nil) {
         self.init(bytes: bytes, length: length, copy: false, deallocator: deallocator)
     }
+
     public convenience init(contentsOfFile path: String, options readOptionsMask: ReadingOptions = []) throws {
         let readResult = try NSData.readBytesFromFileWithExtendedAttributes(path, options: readOptionsMask)
         self.init(bytes: readResult.bytes, length: readResult.length, copy: false, deallocator: readResult.deallocator)
@@ -380,7 +381,10 @@
         }
         
         let length = Int(info.st_size)
-        
+        if length == 0 && (info.st_mode & S_IFMT == S_IFREG) {
+            return try readZeroSizeFile(fd)
+        }
+
         if options.contains(.alwaysMapped) {
             let data = mmap(nil, length, PROT_READ, MAP_PRIVATE, fd, 0)
             
@@ -414,6 +418,37 @@
             free(buffer)
         }
     }
+
+    internal static func readZeroSizeFile(_ fd: Int32) throws -> NSDataReadResult {
+        let blockSize = 1024 * 1024 // 1MB
+        var data: UnsafeMutableRawPointer? = nil
+        var bytesRead = 0
+        var amt = 0
+
+        repeat {
+            data = realloc(data, bytesRead + blockSize)
+            amt = read(fd, data!.advanced(by: bytesRead), blockSize)
+
+            // Dont continue on EINTR or EAGAIN as the file position may not
+            // have changed, see read(2).
+            if amt < 0 {
+                free(data!)
+                throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
+            }
+            bytesRead += amt
+        } while amt > 0
+
+        if bytesRead == 0 {
+            free(data!)
+            data = malloc(0)
+        } else {
+            data = realloc(data, bytesRead) // shrink down the allocated block.
+        }
+
+        return NSDataReadResult(bytes: data!, length: bytesRead) { buffer, length in
+            free(buffer)
+        }
+    }
     
     internal func makeTemporaryFile(inDirectory dirPath: String) throws -> (Int32, String) {
         let template = dirPath._nsObject.appendingPathComponent("tmp.XXXXXX")
@@ -956,6 +991,19 @@
     }
 }
 
+extension NSData {
+    internal func _isCompact() -> Bool {
+        var regions = 0
+        enumerateBytes { (_, _, stop) in
+            regions += 1
+            if regions > 1 {
+                stop.pointee = true
+            }
+        }
+        return regions <= 1
+    }
+}
+
 extension NSData : _StructTypeBridgeable {
     public typealias _StructType = Data
     public func _bridgeToSwift() -> Data {
diff --git a/Foundation/NSDictionary.swift b/Foundation/NSDictionary.swift
index f331104..18392f4 100644
--- a/Foundation/NSDictionary.swift
+++ b/Foundation/NSDictionary.swift
@@ -32,6 +32,10 @@
         return nil
     }
     
+    open func value(forKey key: String) -> Any? {
+        NSUnsupported()
+    }
+    
     open func keyEnumerator() -> NSEnumerator {
         guard type(of: self) === NSDictionary.self || type(of: self) === NSMutableDictionary.self else {
             NSRequiresConcreteImplementation()
@@ -40,6 +44,23 @@
         return NSGeneratorEnumerator(_storage.keys.map { _SwiftValue.fetch(nonOptional: $0) }.makeIterator())
     }
     
+    @available(*, deprecated)
+    public convenience init?(contentsOfFile path: String) {
+        self.init(contentsOf: URL(fileURLWithPath: path))
+    }
+    
+    @available(*, deprecated)
+    public convenience init?(contentsOf url: URL) {
+        do {
+            guard let plistDoc = try? Data(contentsOf: url) else { return nil }
+            let plistDict = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Dictionary<AnyHashable,Any>
+            guard let plistDictionary = plistDict else { return nil }
+            self.init(dictionary: plistDictionary)
+        } catch {
+            return nil
+        }
+    }
+    
     public override convenience init() {
         self.init(objects: [], forKeys: [], count: 0)
     }
@@ -467,11 +488,11 @@
                 lock.lock()
                 var stop = sharedStop
                 lock.unlock()
-                if stop { return }
+                if stop.boolValue { return }
                 
                 closure(keys[idx], objects[idx], &stop)
                 
-                if stop {
+                if stop.boolValue {
                     lock.lock()
                     sharedStop = stop
                     lock.unlock()
@@ -583,20 +604,6 @@
         super.init(objects: objects, forKeys: keys, count: cnt)
     }
     
-    public convenience init?(contentsOfFile path: String) {
-        self.init(contentsOfURL: URL(fileURLWithPath: path))
-    }
-    
-    public convenience init?(contentsOfURL url: URL) {
-        do {
-            guard let plistDoc = try? Data(contentsOf: url) else { return nil }
-            let plistDict = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Dictionary<AnyHashable,Any>
-            guard let plistDictionary = plistDict else { return nil }
-            self.init(dictionary: plistDictionary)
-        } catch {
-            return nil
-        }
-    }
 }
 
 extension NSMutableDictionary {
diff --git a/Foundation/NSIndexSet.swift b/Foundation/NSIndexSet.swift
index f621657..4a96e8a 100644
--- a/Foundation/NSIndexSet.swift
+++ b/Foundation/NSIndexSet.swift
@@ -396,9 +396,9 @@
         let iteration = withoutActuallyEscaping(block) { (closure: @escaping (P, UnsafeMutablePointer<ObjCBool>) -> R) -> (Int) -> Void in
             return { (rangeIdx) in
                 lock.lock()
-                var stop = sharedStop
+                var stop = ObjCBool(sharedStop)
                 lock.unlock()
-                if stop { return }
+                if stop.boolValue { return }
                 
                 let idx = rangeSequence.index(rangeSequence.startIndex, offsetBy: Int64(rangeIdx))
                 let curRange = rangeSequence[idx]
@@ -407,9 +407,9 @@
                     if intersection.length > 0 {
                         let _ = closure(intersection as! P, &stop)
                     }
-                    if stop {
+                    if stop.boolValue {
                         lock.lock()
-                        sharedStop = stop
+                        sharedStop = stop.boolValue
                         lock.unlock()
                         return
                     }
@@ -426,9 +426,9 @@
                         } else {
                             let _ = closure(idx as! P, &stop)
                         }
-                        if stop {
+                        if stop.boolValue {
                             lock.lock()
-                            sharedStop = stop
+                            sharedStop = stop.boolValue
                             lock.unlock()
                             return
                         }
diff --git a/Foundation/NSKeyedArchiver.swift b/Foundation/NSKeyedArchiver.swift
index 3790990..6df2ae1 100644
--- a/Foundation/NSKeyedArchiver.swift
+++ b/Foundation/NSKeyedArchiver.swift
@@ -553,9 +553,11 @@
         }
         
         // check replacement cache
-        objectToEncode = self._replacementMap[object as! AnyHashable]
-        if objectToEncode != nil {
-            return objectToEncode
+        if let hashable = object as? AnyHashable {
+            objectToEncode = self._replacementMap[hashable]
+            if objectToEncode != nil {
+                return objectToEncode
+            }
         }
         
         // object replaced by NSObject.replacementObject(for:)
diff --git a/Foundation/NSKeyedUnarchiver.swift b/Foundation/NSKeyedUnarchiver.swift
index b977cc8..d75a664 100644
--- a/Foundation/NSKeyedUnarchiver.swift
+++ b/Foundation/NSKeyedUnarchiver.swift
@@ -86,7 +86,7 @@
         return root
     }
     
-    public convenience init(forReadingWithData data: Data) {
+    public convenience init(forReadingWith data: Data) {
         self.init(stream: Stream.data(data))
     }
     
@@ -863,7 +863,7 @@
     }
 
     open class func unarchiveTopLevelObjectWithData(_ data: Data) throws -> Any? {
-        let keyedUnarchiver = NSKeyedUnarchiver(forReadingWithData: data)
+        let keyedUnarchiver = NSKeyedUnarchiver(forReadingWith: data)
         let root = try keyedUnarchiver.decodeTopLevelObject(forKey: NSKeyedArchiveRootObjectKey)
         keyedUnarchiver.finishDecoding()
         return root
diff --git a/Foundation/NSLock.swift b/Foundation/NSLock.swift
index e166b80..f4b41d0 100644
--- a/Foundation/NSLock.swift
+++ b/Foundation/NSLock.swift
@@ -230,12 +230,16 @@
         }
         var ts = timespec()
         ts.tv_sec = Int(floor(ti))
-        ts.tv_nsec = Int((ti - Double(ts.tv_sec)) * 1000000000.0)
+        ts.tv_nsec = Int((ti - Double(ts.tv_sec)) * 1_000_000_000.0)
         var tv = timeval()
         withUnsafeMutablePointer(to: &tv) { t in
             gettimeofday(t, nil)
             ts.tv_sec += t.pointee.tv_sec
-            ts.tv_nsec += Int((t.pointee.tv_usec * 1000000) / 1000000000)
+            ts.tv_nsec += Int(t.pointee.tv_usec) * 1000
+            if ts.tv_nsec >= 1_000_000_000 {
+                ts.tv_sec += ts.tv_nsec / 1_000_000_000
+                ts.tv_nsec = ts.tv_nsec % 1_000_000_000
+            }
         }
         let retVal: Int32 = withUnsafePointer(to: &ts) { t in
             return pthread_cond_timedwait(cond, mutex, t)
diff --git a/Foundation/NSNotification.swift b/Foundation/NSNotification.swift
index 688b86a..b848d6d 100644
--- a/Foundation/NSNotification.swift
+++ b/Foundation/NSNotification.swift
@@ -169,7 +169,7 @@
         }
     }
 
-    open func post(name aName: Notification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil) {
+    open func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil) {
         let notification = Notification(name: aName, object: anObject, userInfo: aUserInfo)
         post(notification)
     }
@@ -187,8 +187,13 @@
             self._observers = _observers.filterOutObserver(observer, name: aName, object: object)
         })
     }
-    
-    open func addObserver(forName name: Notification.Name?, object obj: Any?, queue: OperationQueue?, usingBlock block: @escaping (Notification) -> Void) -> NSObjectProtocol {
+
+    @available(*,obsoleted:4.0,renamed:"addObserver(forName:object:queue:using:)")
+    open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, usingBlock block: @escaping (Notification) -> Void) -> NSObjectProtocol {
+        return addObserver(forName: name, object: obj, queue: queue, using: block)
+    }
+
+    open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol {
         let object = NSObject()
         
         let newObserver = NSNotificationReceiver()
diff --git a/Foundation/NSNumber.swift b/Foundation/NSNumber.swift
index b72bdeb..7dc8cc8 100644
--- a/Foundation/NSNumber.swift
+++ b/Foundation/NSNumber.swift
@@ -32,158 +32,523 @@
 internal let kCFNumberSInt128Type: CFNumberType = 17
 #endif
 
+extension Int8 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int8Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int8Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int8Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int8?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int8?) -> Bool {
+        guard let value = Int8(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int8 {
+        var result: Int8?
+        guard let src = source else { return Int8(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int8(0) }
+        return result!
+    }
+}
+
+extension UInt8 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint8Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint8Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint8Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt8?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt8?) -> Bool {
+        guard let value = UInt8(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt8 {
+        var result: UInt8?
+        guard let src = source else { return UInt8(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt8(0) }
+        return result!
+    }
+}
+
+extension Int16 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int16Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int16Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int16Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int16?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int16?) -> Bool {
+        guard let value = Int16(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int16 {
+        var result: Int16?
+        guard let src = source else { return Int16(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int16(0) }
+        return result!
+    }
+}
+
+extension UInt16 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint16Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint16Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint16Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt16?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt16?) -> Bool {
+        guard let value = UInt16(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt16 {
+        var result: UInt16?
+        guard let src = source else { return UInt16(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt16(0) }
+        return result!
+    }
+}
+
+extension Int32 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int32Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int32Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int32Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int32?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int32?) -> Bool {
+        guard let value = Int32(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int32 {
+        var result: Int32?
+        guard let src = source else { return Int32(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int32(0) }
+        return result!
+    }
+}
+
+extension UInt32 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint32Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint32Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint32Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt32?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt32?) -> Bool {
+        guard let value = UInt32(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt32 {
+        var result: UInt32?
+        guard let src = source else { return UInt32(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt32(0) }
+        return result!
+    }
+}
+
+extension Int64 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.int64Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.int64Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.int64Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int64?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int64?) -> Bool {
+        guard let value = Int64(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int64 {
+        var result: Int64?
+        guard let src = source else { return Int64(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int64(0) }
+        return result!
+    }
+}
+
+extension UInt64 : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
+    public init(_ number: NSNumber) {
+        self = number.uint64Value
+    }
+
+    public init(truncating number: NSNumber) {
+        self = number.uint64Value
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uint64Value
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
+        return NSNumber(value: self)
+    }
+
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt64?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
+    }
+
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt64?) -> Bool {
+        guard let value = UInt64(exactly: x) else { return false }
+        result = value
+        return true
+    }
+
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt64 {
+        var result: UInt64?
+        guard let src = source else { return UInt64(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt64(0) }
+        return result!
+    }
+}
+
 extension Int : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.intValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.intValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.intValue
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Int?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Int?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Int?) -> Bool {
-        result = source.intValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Int?) -> Bool {
+        guard let value = Int(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Int {
-        if let object = source {
-            var value: Int?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Int {
+        var result: Int?
+        guard let src = source else { return Int(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Int(0) }
+        return result!
     }
 }
 
 extension UInt : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.uintValue
     }
 
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+    public init(truncating number: NSNumber) {
+        self = number.uintValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let value = number.uintValue
+        guard NSNumber(value: value) == number else { return nil }
+        self = value
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout UInt?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout UInt?) -> Bool {
-        result = source.uintValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout UInt?) -> Bool {
+        guard let value = UInt(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> UInt {
-        if let object = source {
-            var value: UInt?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> UInt {
+        var result: UInt?
+        guard let src = source else { return UInt(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return UInt(0) }
+        return result!
     }
 }
 
 extension Float : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.floatValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.floatValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        guard let value = Double(exactly: number) else { return nil }
+        guard let result = Float(exactly: value) else { return nil }
+        self = result
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Float?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Float?) -> Bool {
-        result = source.floatValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) -> Bool {
+        guard let value = Double(exactly: x) else { return false }
+        guard !value.isNaN else {
+            result = Float.nan
+            return true
+        }
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                result = -Float.infinity
+            } else {
+                result = Float.infinity
+            }
+            return true
+        }
+        guard Swift.abs(value) <= Double(Float.greatestFiniteMagnitude) else {
+            return false
+        }
+
+        result = Float(value)
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Float {
-        if let object = source {
-            var value: Float?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0.0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Float {
+        var result: Float?
+        guard let src = source else { return Float(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Float(0) }
+        return result!
     }
 }
 
 extension Double : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.doubleValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.doubleValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        let type = number.objCType.pointee
+        if type == 0x51 {
+            guard let result = Double(exactly: number.uint64Value) else { return nil }
+            self = result
+        } else if type == 0x71 {
+            guard let result = Double(exactly: number.int64Value) else  { return nil }
+            self = result
+        } else {
+            self = number.doubleValue
+        }
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return NSNumber(value: self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Double?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Double?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Double?) -> Bool {
-        result = source.doubleValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Double?) -> Bool {
+        guard let value = Double(exactly: x) else { return false }
+        result = value
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Double {
-        if let object = source {
-            var value: Double?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return 0.0
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Double {
+        var result: Double?
+        guard let src = source else { return Double(0) }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return Double(0) }
+        return result!
     }
 }
 
 extension Bool : _ObjectTypeBridgeable {
+    @available(swift, deprecated: 4, renamed: "init(truncating:)")
     public init(_ number: NSNumber) {
         self = number.boolValue
     }
-    
-    public typealias _ObjectType = NSNumber
-    public func _bridgeToObjectiveC() -> _ObjectType {
+
+    public init(truncating number: NSNumber) {
+        self = number.boolValue
+    }
+
+    public init?(exactly number: NSNumber) {
+        if number === kCFBooleanTrue || NSNumber(value: 1) == number {
+            self = true
+        } else if number === kCFBooleanFalse || NSNumber(value: 0) == number {
+            self = false
+        } else {
+            return nil
+        }
+    }
+
+    public func _bridgeToObjectiveC() -> NSNumber {
         return unsafeBitCast(self ? kCFBooleanTrue : kCFBooleanFalse, to: NSNumber.self)
     }
     
-    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Bool?) {
-        result = _unconditionallyBridgeFromObjectiveC(source)
+    public static func _forceBridgeFromObjectiveC(_ x: NSNumber, result: inout Bool?) {
+        result = _unconditionallyBridgeFromObjectiveC(x)
     }
     
-    @discardableResult
-    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Bool?) -> Bool {
-        result = source.boolValue
+    public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Bool?) -> Bool {
+        result = x.boolValue
         return true
     }
     
-    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Bool {
-        if let object = source {
-            var value: Bool?
-            _conditionallyBridgeFromObjectiveC(object, result: &value)
-            return value!
-        } else {
-            return false
-        }
+    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Bool {
+        var result: Bool?
+        guard let src = source else { return false }
+        guard _conditionallyBridgeFromObjectiveC(src, result: &result) else { return false }
+        return result!
     }
 }
 
@@ -226,7 +591,7 @@
         case let other as Bool:
             return boolValue == other
         case let other as NSNumber:
-            return CFEqual(_cfObject, other._cfObject)
+            return compare(other) == .orderedSame
         default:
             return false
         }
@@ -256,7 +621,7 @@
             fatalError("unsupported CFNumberType: '\(numberType)'")
         }
     }
-    
+
     deinit {
         _CFDeinit(self)
     }
@@ -460,6 +825,12 @@
         CFNumberGetValue(_cfObject, kCFNumberSInt128Type, &value)
         return .init(truncatingIfNeeded: value.low)
     }
+
+    private var int128Value: CFSInt128Struct {
+        var value = CFSInt128Struct(high: 0, low: 0)
+        CFNumberGetValue(_cfObject, kCFNumberSInt128Type, &value)
+        return value
+    }
     
     open var floatValue: Float {
         var value: Float = 0
@@ -516,33 +887,49 @@
     }
 
     open func compare(_ otherNumber: NSNumber) -> ComparisonResult {
-        switch (objCType.pointee, otherNumber.objCType.pointee) {
-        case (0x66, _), (_, 0x66), (0x66, 0x66): fallthrough // 'f' float
-        case (0x64, _), (_, 0x64), (0x64, 0x64):             // 'd' double
+        switch (_cfNumberType(), otherNumber._cfNumberType()) {
+        case (kCFNumberFloatType, _), (_, kCFNumberFloatType): fallthrough
+        case (kCFNumberDoubleType, _), (_, kCFNumberDoubleType):
             let (lhs, rhs) = (doubleValue, otherNumber.doubleValue)
+            // Apply special handling for NaN as <, >, == always return false
+            // when comparing with NaN
+            if lhs.isNaN && rhs.isNaN { return .orderedSame }
+            if lhs.isNaN { return .orderedAscending }
+            if rhs.isNaN { return .orderedDescending }
+
             if lhs < rhs { return .orderedAscending }
             if lhs > rhs { return .orderedDescending }
             return .orderedSame
-        case (0x51, _), (_, 0x51), (0x51, 0x51):             // 'q' unsigned long long
-            let (lhs, rhs) = (uint64Value, otherNumber.uint64Value)
-            if lhs < rhs { return .orderedAscending }
-            if lhs > rhs { return .orderedDescending }
-            return .orderedSame
-        case (_, _):
-            let (lhs, rhs) = (int64Value, otherNumber.int64Value)
-            if lhs < rhs { return .orderedAscending }
-            if lhs > rhs { return .orderedDescending }
+
+        default: // For signed and unsigned integers expand upto S128Int
+            let (lhs, rhs) = (int128Value, otherNumber.int128Value)
+            if lhs.high < rhs.high { return .orderedAscending }
+            if lhs.high > rhs.high { return .orderedDescending }
+            if lhs.low < rhs.low { return .orderedAscending }
+            if lhs.low > rhs.low { return .orderedDescending }
             return .orderedSame
         }
     }
 
+    private static let _numberFormatterForNilLocale: CFNumberFormatter = {
+        let formatter: CFNumberFormatter
+        formatter = CFNumberFormatterCreate(nil, CFLocaleCopyCurrent(), kCFNumberFormatterNoStyle)
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMaxFractionDigits, 15._bridgeToObjectiveC())
+        return formatter
+    }()
+
     open func description(withLocale locale: Locale?) -> String {
+        // CFNumberFormatterCreateStringWithNumber() does not like numbers of type
+        // SInt128Type, as it loses the type when looking it up and treats it as
+        // an SInt64Type, so special case them.
+        if _CFNumberGetType2(_cfObject) == kCFNumberSInt128Type {
+            return String(format: "%@", unsafeBitCast(_cfObject, to: UnsafePointer<CFNumber>.self))
+        }
+
         let aLocale = locale
         let formatter: CFNumberFormatter
         if (aLocale == nil) {
-            formatter = CFNumberFormatterCreate(nil, CFLocaleCopyCurrent(), kCFNumberFormatterNoStyle)
-            CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMaxFractionDigits, 15._bridgeToObjectiveC())
-
+            formatter = NSNumber._numberFormatterForNilLocale
         } else {
             formatter = CFNumberFormatterCreate(nil, aLocale?._cfObject, kCFNumberFormatterDecimalStyle)
         }
diff --git a/Foundation/NSObjCRuntime.swift b/Foundation/NSObjCRuntime.swift
index 70db11e..788b1ef 100644
--- a/Foundation/NSObjCRuntime.swift
+++ b/Foundation/NSObjCRuntime.swift
@@ -202,6 +202,13 @@
     fatalError("\(fn) is not yet implemented", file: file, line: line)
 }
 
+internal func NSUnsupported(_ fn: String = #function, file: StaticString = #file, line: UInt = #line) -> Never {
+    #if os(Android)
+    NSLog("\(fn) is not supported on this platform. \(file):\(line)")
+    #endif
+    fatalError("\(fn) is not supported on this platform", file: file, line: line)
+}
+
 internal func NSInvalidArgument(_ message: String, method: String = #function, file: StaticString = #file, line: UInt = #line) -> Never {
     fatalError("\(method): \(message)", file: file, line: line)
 }
diff --git a/Foundation/NSPathUtilities.swift b/Foundation/NSPathUtilities.swift
index 4590787..f0b65b4 100644
--- a/Foundation/NSPathUtilities.swift
+++ b/Foundation/NSPathUtilities.swift
@@ -35,18 +35,16 @@
 
 internal extension String {
     
-    internal var _startOfLastPathComponent : String.CharacterView.Index {
+    internal var _startOfLastPathComponent : String.Index {
         precondition(!hasSuffix("/") && length > 1)
         
-        let characterView = characters
-        let startPos = characterView.startIndex
-        let endPos = characterView.endIndex
-        var curPos = endPos
+        let startPos = startIndex
+        var curPos = endIndex
         
         // Find the beginning of the component
         while curPos > startPos {
-            let prevPos = characterView.index(before: curPos)
-            if characterView[prevPos] == "/" {
+            let prevPos = index(before: curPos)
+            if self[prevPos] == "/" {
                 break
             }
             curPos = prevPos
@@ -55,19 +53,16 @@
 
     }
 
-    internal var _startOfPathExtension : String.CharacterView.Index? {
+    internal var _startOfPathExtension : String.Index? {
         precondition(!hasSuffix("/"))
         
-        let characterView = self.characters
-        let endPos = characterView.endIndex
-        var curPos = endPos
-        
+        var curPos = endIndex
         let lastCompStartPos = _startOfLastPathComponent
         
         // Find the beginning of the extension
         while curPos > lastCompStartPos {
-            let prevPos = characterView.index(before: curPos)
-            let char = characterView[prevPos]
+            let prevPos = index(before: curPos)
+            let char = self[prevPos]
             if char == "/" {
                 return nil
             } else if char == "." {
@@ -125,7 +120,7 @@
             }
         }
         if stripTrailing && result.length > 1 && result.hasSuffix("/") {
-            result.remove(at: result.characters.index(before: result.characters.endIndex))
+            result.remove(at: result.index(before: result.endIndex))
         }
         return result
     }
@@ -181,7 +176,7 @@
             return fixedSelf
         }
         
-        return String(fixedSelf.characters.suffix(from: fixedSelf._startOfLastPathComponent))
+        return String(fixedSelf.suffix(from: fixedSelf._startOfLastPathComponent))
     }
     
     public var deletingLastPathComponent : String {
@@ -202,7 +197,7 @@
         
         // all common cases
         case let startOfLast:
-            return String(fixedSelf.characters.prefix(upTo: fixedSelf.index(before: startOfLast)))
+            return String(fixedSelf.prefix(upTo: fixedSelf.index(before: startOfLast)))
         }
     }
     
@@ -236,7 +231,7 @@
             }
         }
         if stripTrailing && result.hasSuffix("/") {
-            result.remove(at: result.characters.index(before: result.characters.endIndex))
+            result.remove(at: result.index(before: result.endIndex))
         }
         return result
     }
@@ -265,7 +260,7 @@
         }
 
         if let extensionPos = fixedSelf._startOfPathExtension {
-            return String(fixedSelf.characters.suffix(from: extensionPos))
+            return String(fixedSelf.suffix(from: extensionPos))
         } else {
             return ""
         }
@@ -277,7 +272,7 @@
             return fixedSelf
         }
         if let extensionPos = (fixedSelf._startOfPathExtension) {
-            return String(fixedSelf.characters.prefix(upTo: fixedSelf.characters.index(before: extensionPos)))
+            return String(fixedSelf.prefix(upTo: fixedSelf.index(before: extensionPos)))
         } else {
             return fixedSelf
         }
@@ -297,9 +292,9 @@
             return _swiftObject
         }
 
-        let endOfUserName = _swiftObject.characters.index(of: "/") ?? _swiftObject.endIndex
-        let startOfUserName = _swiftObject.characters.index(after: _swiftObject.characters.startIndex)
-        let userName = String(_swiftObject.characters[startOfUserName..<endOfUserName])
+        let endOfUserName = _swiftObject.index(of: "/") ?? _swiftObject.endIndex
+        let startOfUserName = _swiftObject.index(after: _swiftObject.startIndex)
+        let userName = String(_swiftObject[startOfUserName..<endOfUserName])
         let optUserName: String? = userName.isEmpty ? nil : userName
         
         guard let homeDir = NSHomeDirectoryForUser(optUserName) else {
@@ -413,9 +408,9 @@
             return false
         }
         
-        var isDirectory = false
+        var isDirectory: ObjCBool = false
         let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory)
-        return exists && isDirectory
+        return exists && isDirectory.boolValue
     }
     
     internal typealias _FileNamePredicate = (String?) -> Bool
@@ -478,7 +473,7 @@
             return strings.first
         }
         
-        var sequences = strings.map({ $0.characters.makeIterator() })
+        var sequences = strings.map({ $0.makeIterator() })
         var prefix: [Character] = []
         loop: while true {
             var char: Character? = nil
@@ -490,8 +485,8 @@
                 }
                 
                 if char != nil {
-                    let lhs = caseSensitive ? char : String(char!).lowercased().characters.first!
-                    let rhs = caseSensitive ? c : String(c).lowercased().characters.first!
+                    let lhs = caseSensitive ? char : String(char!).lowercased().first!
+                    let rhs = caseSensitive ? c : String(c).lowercased().first!
                     if lhs != rhs {
                         break loop
                     }
diff --git a/Foundation/NSRegularExpression.swift b/Foundation/NSRegularExpression.swift
index ec4a88e..8eea556 100644
--- a/Foundation/NSRegularExpression.swift
+++ b/Foundation/NSRegularExpression.swift
@@ -85,7 +85,7 @@
         if let regex = _CFRegularExpressionCreate(kCFAllocatorSystemDefault, pattern._cfObject, opt, &error) {
             _internal = regex
         } else {
-            throw error!.takeRetainedValue()._nsObject
+            throw error!.takeRetainedValue()
         }
     }
     
@@ -114,33 +114,36 @@
     }
 }
 
-public struct NSMatchingOptions : OptionSet {
-    public let rawValue : UInt
-    public init(rawValue: UInt) { self.rawValue = rawValue }
-    
-    public static let reportProgress = NSMatchingOptions(rawValue: 1 << 0) /* Call the block periodically during long-running match operations. */
-    public static let reportCompletion = NSMatchingOptions(rawValue: 1 << 1) /* Call the block once after the completion of any matching. */
-    public static let anchored = NSMatchingOptions(rawValue: 1 << 2) /* Limit matches to those at the start of the search range. */
-    public static let withTransparentBounds = NSMatchingOptions(rawValue: 1 << 3) /* Allow matching to look beyond the bounds of the search range. */
-    public static let withoutAnchoringBounds = NSMatchingOptions(rawValue: 1 << 4) /* Prevent ^ and $ from automatically matching the beginning and end of the search range. */
-    internal static let OmitResult = NSMatchingOptions(rawValue: 1 << 13)
-}
+extension NSRegularExpression {
 
-public struct NSMatchingFlags : OptionSet {
-    public let rawValue : UInt
-    public init(rawValue: UInt) { self.rawValue = rawValue }
-    
-    public static let progress = NSMatchingFlags(rawValue: 1 << 0) /* Set when the block is called to report progress during a long-running match operation. */
-    public static let completed = NSMatchingFlags(rawValue: 1 << 1) /* Set when the block is called after completion of any matching. */
-    public static let hitEnd = NSMatchingFlags(rawValue: 1 << 2) /* Set when the current match operation reached the end of the search range. */
-    public static let requiredEnd = NSMatchingFlags(rawValue: 1 << 3) /* Set when the current match depended on the location of the end of the search range. */
-    public static let internalError = NSMatchingFlags(rawValue: 1 << 4) /* Set when matching failed due to an internal error. */
+    public struct MatchingOptions : OptionSet {
+        public let rawValue : UInt
+        public init(rawValue: UInt) { self.rawValue = rawValue }
+
+        public static let reportProgress = MatchingOptions(rawValue: 1 << 0) /* Call the block periodically during long-running match operations. */
+        public static let reportCompletion = MatchingOptions(rawValue: 1 << 1) /* Call the block once after the completion of any matching. */
+        public static let anchored = MatchingOptions(rawValue: 1 << 2) /* Limit matches to those at the start of the search range. */
+        public static let withTransparentBounds = MatchingOptions(rawValue: 1 << 3) /* Allow matching to look beyond the bounds of the search range. */
+        public static let withoutAnchoringBounds = MatchingOptions(rawValue: 1 << 4) /* Prevent ^ and $ from automatically matching the beginning and end of the search range. */
+        internal static let OmitResult = MatchingOptions(rawValue: 1 << 13)
+    }
+
+    public struct MatchingFlags : OptionSet {
+        public let rawValue : UInt
+        public init(rawValue: UInt) { self.rawValue = rawValue }
+
+        public static let progress = MatchingFlags(rawValue: 1 << 0) /* Set when the block is called to report progress during a long-running match operation. */
+        public static let completed = MatchingFlags(rawValue: 1 << 1) /* Set when the block is called after completion of any matching. */
+        public static let hitEnd = MatchingFlags(rawValue: 1 << 2) /* Set when the current match operation reached the end of the search range. */
+        public static let requiredEnd = MatchingFlags(rawValue: 1 << 3) /* Set when the current match depended on the location of the end of the search range. */
+        public static let internalError = MatchingFlags(rawValue: 1 << 4) /* Set when matching failed due to an internal error. */
+    }
 }
 
 internal class _NSRegularExpressionMatcher {
     var regex: NSRegularExpression
-    var block: (NSTextCheckingResult?, NSMatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void
-    init(regex: NSRegularExpression, block: @escaping (NSTextCheckingResult?, NSMatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void) {
+    var block: (NSTextCheckingResult?, NSRegularExpression.MatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void
+    init(regex: NSRegularExpression, block: @escaping (NSTextCheckingResult?, NSRegularExpression.MatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void) {
         self.regex = regex
         self.block = block
     }
@@ -155,16 +158,16 @@
         let opts = options
 #endif
         stop.withMemoryRebound(to: ObjCBool.self, capacity: 1, {
-            matcher.block(nil, NSMatchingFlags(rawValue: opts), $0)
+            matcher.block(nil, NSRegularExpression.MatchingFlags(rawValue: opts), $0)
         })
     } else {
         let result = ranges!.withMemoryRebound(to: NSRange.self, capacity: count) { rangePtr in
             NSTextCheckingResult.regularExpressionCheckingResultWithRanges(rangePtr, count: count, regularExpression: matcher.regex)
         }
 #if os(OSX) || os(iOS)
-        let flags = NSMatchingFlags(rawValue: options.rawValue)
+        let flags = NSRegularExpression.MatchingFlags(rawValue: options.rawValue)
 #else
-        let flags = NSMatchingFlags(rawValue: options)
+        let flags = NSRegularExpression.MatchingFlags(rawValue: options)
 #endif
         stop.withMemoryRebound(to: ObjCBool.self, capacity: 1, {
             matcher.block(result, flags, $0)
@@ -177,7 +180,7 @@
     /* The fundamental matching method on NSRegularExpression is a block iterator.  There are several additional convenience methods, for returning all matches at once, the number of matches, the first match, or the range of the first match.  Each match is specified by an instance of NSTextCheckingResult (of type NSTextCheckingTypeRegularExpression) in which the overall match range is given by the range property (equivalent to range at:0) and any capture group ranges are given by range at: for indexes from 1 to numberOfCaptureGroups.  {NSNotFound, 0} is used if a particular capture group does not participate in the match.
     */
     
-    public func enumerateMatches(in string: String, options: NSMatchingOptions, range: NSRange, using block: @escaping (NSTextCheckingResult?, NSMatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
+    public func enumerateMatches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange, using block: @escaping (NSTextCheckingResult?, NSRegularExpression.MatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         let matcher = _NSRegularExpressionMatcher(regex: self, block: block)
         withExtendedLifetime(matcher) { (m: _NSRegularExpressionMatcher) -> Void in
 #if os(OSX) || os(iOS)
@@ -189,9 +192,9 @@
         }
     }
     
-    public func matches(in string: String, options: NSMatchingOptions, range: NSRange) -> [NSTextCheckingResult] {
+    public func matches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [NSTextCheckingResult] {
         var matches = [NSTextCheckingResult]()
-        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
+        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
             if let match = result {
                 matches.append(match)
             }
@@ -200,7 +203,7 @@
         
     }
     
-    public func numberOfMatches(in string: String, options: NSMatchingOptions, range: NSRange) -> Int {
+    public func numberOfMatches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> Int {
         var count = 0
         enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion).union(.OmitResult), range: range) {_,_,_ in 
             count += 1
@@ -208,18 +211,18 @@
         return count
     }
     
-    public func firstMatch(in string: String, options: NSMatchingOptions, range: NSRange) -> NSTextCheckingResult? {
+    public func firstMatch(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> NSTextCheckingResult? {
         var first: NSTextCheckingResult?
-        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
+        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
             first = result
             stop.pointee = true
         }
         return first
     }
     
-    public func rangeOfFirstMatch(in string: String, options: NSMatchingOptions, range: NSRange) -> NSRange {
+    public func rangeOfFirstMatch(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> NSRange {
         var firstRange = NSMakeRange(NSNotFound, 0)
-        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
+        enumerateMatches(in: string, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range) { (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
             if let match = result {
                 firstRange = match.range
             } else {
@@ -244,7 +247,7 @@
     
     /* NSRegularExpression also provides find-and-replace methods for both immutable and mutable strings.  The replacement is treated as a template, with $0 being replaced by the contents of the matched range, $1 by the contents of the first capture group, and so on.  Additional digits beyond the maximum required to represent the number of capture groups will be treated as ordinary characters, as will a $ not followed by digits.  Backslash will escape both $ and itself.
     */
-    public func stringByReplacingMatches(in string: String, options: NSMatchingOptions, range: NSRange, withTemplate templ: String) -> String {
+    public func stringByReplacingMatches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange, withTemplate templ: String) -> String {
         var str: String = ""
         let length = string.length
         var previousRange = NSMakeRange(0, 0)
@@ -272,7 +275,7 @@
         return str
     }
     
-    public func replaceMatches(in string: NSMutableString, options: NSMatchingOptions, range: NSRange, withTemplate templ: String) -> Int {
+    public func replaceMatches(in string: NSMutableString, options: NSRegularExpression.MatchingOptions = [], range: NSRange, withTemplate templ: String) -> Int {
         let results = matches(in: string._swiftObject, options: options.subtracting(.reportProgress).subtracting(.reportCompletion), range: range)
         var count = 0
         var offset = 0
diff --git a/Foundation/NSSet.swift b/Foundation/NSSet.swift
index fdd5b99..939c358 100644
--- a/Foundation/NSSet.swift
+++ b/Foundation/NSSet.swift
@@ -255,7 +255,7 @@
             withUnsafeMutablePointer(to: &stop) { stop in
                 block(obj, stop)
             }
-            if stop {
+            if stop.boolValue {
                 break
             }
         }
diff --git a/Foundation/NSString.swift b/Foundation/NSString.swift
index 3432118..b27719a 100644
--- a/Foundation/NSString.swift
+++ b/Foundation/NSString.swift
@@ -488,7 +488,7 @@
     internal func _rangeOfRegularExpressionPattern(regex pattern: String, options mask: CompareOptions, range searchRange: NSRange, locale: Locale?) -> NSRange {
         var matchedRange = NSMakeRange(NSNotFound, 0)
         let regexOptions: NSRegularExpression.Options = mask.contains(.caseInsensitive) ? .caseInsensitive : []
-        let matchingOptions: NSMatchingOptions = mask.contains(.anchored) ? .anchored : []
+        let matchingOptions: NSRegularExpression.MatchingOptions = mask.contains(.anchored) ? .anchored : []
         if let regex = _createRegexForPattern(pattern, regexOptions) {
             matchedRange = regex.rangeOfFirstMatch(in: _swiftObject, options: matchingOptions, range: searchRange)
         }
@@ -1061,7 +1061,7 @@
     
     internal func _stringByReplacingOccurrencesOfRegularExpressionPattern(_ pattern: String, withTemplate replacement: String, options: CompareOptions, range: NSRange) -> String {
         let regexOptions: NSRegularExpression.Options = options.contains(.caseInsensitive) ? .caseInsensitive : []
-        let matchingOptions: NSMatchingOptions = options.contains(.anchored) ? .anchored : []
+        let matchingOptions: NSRegularExpression.MatchingOptions = options.contains(.anchored) ? .anchored : []
         if let regex = _createRegexForPattern(pattern, regexOptions) {
             return regex.stringByReplacingMatches(in: _swiftObject, options: matchingOptions, range: range, withTemplate: replacement)
         }
@@ -1221,18 +1221,6 @@
             free(bytes)
         }
     }
-    
-    public convenience init?(CString nullTerminatedCString: UnsafePointer<Int8>, encoding: UInt) {
-        guard let cf = CFStringCreateWithCString(kCFAllocatorSystemDefault, nullTerminatedCString, CFStringConvertNSStringEncodingToEncoding(encoding)) else {
-            return nil
-        }
-        var str: String?
-        if String._conditionallyBridgeFromObjectiveC(cf._nsObject, result: &str) {
-            self.init(str!)
-        } else {
-            return nil
-        }
-    }
 
     public convenience init(contentsOf url: URL, encoding enc: UInt) throws {
         let readResult = try NSData(contentsOf: url, options: [])
@@ -1260,33 +1248,37 @@
     public convenience init(contentsOf url: URL, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
         let readResult = try NSData(contentsOf: url, options:[])
 
-        var offset = 0
+        let encoding: UInt
+        let offset: Int
         let bytePtr = readResult.bytes.bindMemory(to: UInt8.self, capacity:readResult.length)
         if readResult.length >= 4 && bytePtr[0] == 0xFF && bytePtr[1] == 0xFE && bytePtr[2] == 0x00 && bytePtr[3] == 0x00 {
-            enc?.pointee = String.Encoding.utf32LittleEndian.rawValue
+            encoding = String.Encoding.utf32LittleEndian.rawValue
             offset = 4
         }
         else if readResult.length >= 2 && bytePtr[0] == 0xFE && bytePtr[1] == 0xFF {
-            enc?.pointee = String.Encoding.utf16BigEndian.rawValue
+            encoding = String.Encoding.utf16BigEndian.rawValue
             offset = 2
         }
         else if readResult.length >= 2 && bytePtr[0] == 0xFF && bytePtr[1] == 0xFE {
-            enc?.pointee = String.Encoding.utf16LittleEndian.rawValue
+            encoding = String.Encoding.utf16LittleEndian.rawValue
             offset = 2
         }
         else if readResult.length >= 4 && bytePtr[0] == 0x00 && bytePtr[1] == 0x00 && bytePtr[2] == 0xFE && bytePtr[3] == 0xFF {
-            enc?.pointee = String.Encoding.utf32BigEndian.rawValue
+            encoding = String.Encoding.utf32BigEndian.rawValue
             offset = 4
         }
         else {
             //Need to work on more conditions. This should be the default
-            enc?.pointee = String.Encoding.utf8.rawValue
+            encoding = String.Encoding.utf8.rawValue
+            offset = 0
         }
 
+        enc?.pointee = encoding
+
         // Since the encoding being passed includes the byte order the BOM wont be checked or skipped, so pass offset to
         // manually skip the BOM header.
-        guard let enc = enc, let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr + offset, readResult.length - offset,
-                                                              CFStringConvertNSStringEncodingToEncoding(enc.pointee), true) else {
+        guard let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr + offset, readResult.length - offset,
+                                               CFStringConvertNSStringEncodingToEncoding(encoding), true) else {
             throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
                 "NSDebugDescription" : "Unable to create a string using the specified encoding."
                 ])
@@ -1298,11 +1290,11 @@
             throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadInapplicableStringEncoding.rawValue, userInfo: [
                 "NSDebugDescription" : "Unable to bridge CFString to String."
                 ])
-        }    
+        }
     }
     
     public convenience init(contentsOfFile path: String, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
-        NSUnimplemented()    
+        try self.init(contentsOf: URL(fileURLWithPath: path), usedEncoding: enc)
     }
 }
 
@@ -1391,7 +1383,7 @@
     
     internal func _replaceOccurrencesOfRegularExpressionPattern(_ pattern: String, withTemplate replacement: String, options: CompareOptions, range searchRange: NSRange) -> Int {
         let regexOptions: NSRegularExpression.Options = options.contains(.caseInsensitive) ? .caseInsensitive : []
-        let matchingOptions: NSMatchingOptions = options.contains(.anchored) ? .anchored : []
+        let matchingOptions: NSRegularExpression.MatchingOptions = options.contains(.anchored) ? .anchored : []
         if let regex = _createRegexForPattern(pattern, regexOptions) {
             return regex.replaceMatches(in: self, options: matchingOptions, range: searchRange, withTemplate: replacement)
         }
diff --git a/Foundation/NSStringAPI.swift b/Foundation/NSStringAPI.swift
index 49d374a..1b57164 100644
--- a/Foundation/NSStringAPI.swift
+++ b/Foundation/NSStringAPI.swift
@@ -2,11 +2,11 @@
 //
 // 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) 2014 - 2017 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
-// See http://swift.org/LICENSE.txt for license information
-// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,6 +14,20 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Important Note
+// ==============
+//
+// This file is shared between two projects:
+//
+// 1. https://github.com/apple/swift/tree/master/stdlib/public/SDK/Foundation
+// 2. https://github.com/apple/swift-corelibs-foundation/tree/master/Foundation
+//
+// If you change this file, you must update it in both places.
+
+#if !DEPLOYMENT_RUNTIME_SWIFT
+@_exported import Foundation // Clang module
+#endif
+
 // Open Issues
 // ===========
 //
@@ -28,76 +42,38 @@
   return result
 }
 
-func _toNSRange(_ r: Range<String.Index>) -> NSRange {
-  return NSRange(
-    location: r.lowerBound.encodedOffset,
-    length: r.upperBound.encodedOffset - r.lowerBound.encodedOffset)
+#if !DEPLOYMENT_RUNTIME_SWIFT
+// We only need this for UnsafeMutablePointer, but there's not currently a way
+// to write that constraint.
+extension Optional {
+  /// Invokes `body` with `nil` if `self` is `nil`; otherwise, passes the
+  /// address of `object` to `body`.
+  ///
+  /// This is intended for use with Foundation APIs that return an Objective-C
+  /// type via out-parameter where it is important to be able to *ignore* that
+  /// parameter by passing `nil`. (For some APIs, this may allow the
+  /// implementation to avoid some work.)
+  ///
+  /// In most cases it would be simpler to just write this code inline, but if
+  /// `body` is complicated than that results in unnecessarily repeated code.
+  internal func _withNilOrAddress<NSType : AnyObject, ResultType>(
+    of object: inout NSType?,
+    _ body:
+      (AutoreleasingUnsafeMutablePointer<NSType?>?) -> ResultType
+  ) -> ResultType {
+    return self == nil ? body(nil) : body(&object)
+  }
 }
+#endif
 
 extension String {
-
-  //===--- Bridging Helpers -----------------------------------------------===//
-  //===--------------------------------------------------------------------===//
-
-  /// The corresponding `NSString` - a convenience for bridging code.
-  var _ns: NSString {
-    return self._bridgeToObjectiveC()
-  }
-
-  /// Return an `Index` corresponding to the given offset in our UTF-16
-  /// representation.
-  func _index(_ utf16Index: Int) -> Index {
-    return Index(encodedOffset: utf16Index)
-  }
-
-  /// Return a `Range<Index>` corresponding to the given `NSRange` of
-  /// our UTF-16 representation.
-  func _range(_ r: NSRange) -> Range<Index> {
-    return _index(r.location)..<_index(r.location + r.length)
-  }
-
-  /// Return a `Range<Index>?` corresponding to the given `NSRange` of
-  /// our UTF-16 representation.
-  func _optionalRange(_ r: NSRange) -> Range<Index>? {
-    if r.location == NSNotFound {
-      return nil
-    }
-    return _range(r)
-  }
-
-  /// Invoke `body` on an `Int` buffer.  If `index` was converted from
-  /// non-`nil`, convert the buffer to an `Index` and write it into the
-  /// memory referred to by `index`
-  func _withOptionalOutParameter<Result>(
-    _ index: UnsafeMutablePointer<Index>?,
-    _ body: (UnsafeMutablePointer<Int>?) -> Result
-  ) -> Result {
-    var utf16Index: Int = 0
-    let result = (index != nil ? body(&utf16Index) : body(nil))
-    index?.pointee = self._index(utf16Index)
-    return result
-  }
-
-  /// Invoke `body` on an `NSRange` buffer.  If `range` was converted
-  /// from non-`nil`, convert the buffer to a `Range<Index>` and write
-  /// it into the memory referred to by `range`
-  func _withOptionalOutParameter<Result>(
-    _ range: UnsafeMutablePointer<Range<Index>>?,
-    _ body: (UnsafeMutablePointer<NSRange>?) -> Result
-  ) -> Result {
-    var nsRange = NSRange(location: 0, length: 0)
-    let result = (range != nil ? body(&nsRange) : body(nil))
-    range?.pointee = self._range(nsRange)
-    return result
-  }
-
   //===--- Class Methods --------------------------------------------------===//
   //===--------------------------------------------------------------------===//
 
   // @property (class) const NSStringEncoding *availableStringEncodings;
 
-  /// Returns an Array of the encodings string objects support
-  /// in the application's environment.
+  /// An array of the encodings that strings support in the application's
+  /// environment.
   public static var availableStringEncodings: [Encoding] {
     var result = [Encoding]()
     var p = NSString.availableStringEncodings
@@ -110,15 +86,20 @@
 
   // @property (class) NSStringEncoding defaultCStringEncoding;
 
-  /// Returns the C-string encoding assumed for any method accepting
-  /// a C string as an argument.
+  /// The C-string encoding assumed for any method accepting a C string as an
+  /// argument.
   public static var defaultCStringEncoding: Encoding {
     return Encoding(rawValue: NSString.defaultCStringEncoding)
   }
 
   // + (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding
 
-  /// Returns a human-readable string giving the name of a given encoding.
+  /// Returns a human-readable string giving the name of the specified encoding.
+  ///
+  /// - Parameter encoding: A string encoding. For possible values, see
+  ///   `String.Encoding`.
+  /// - Returns: A human-readable string giving the name of `encoding` in the
+  ///   current locale.
   public static func localizedName(
     of encoding: Encoding
   ) -> String {
@@ -137,15 +118,6 @@
       arguments: arguments)
   }
 
-  // + (NSString *)pathWithComponents:(NSArray *)components
-
-  /// Returns a string built from the strings in a given array
-  /// by concatenating them with a path separator between each pair.
-  @available(*, unavailable, message: "Use fileURL(withPathComponents:) on URL instead.")
-  public static func path(withComponents components: [String]) -> String {
-    return (NSURL.fileURL(withPathComponents: components)?.path)!
-  }
-
   //===--------------------------------------------------------------------===//
   // NSString factory functions that have a corresponding constructor
   // are omitted.
@@ -188,453 +160,18 @@
 
   // + (instancetype)stringWithUTF8String:(const char *)bytes
 
-  /// Produces a string created by copying the data from a given
+  /// Creates a string by copying the data from a given
   /// C array of UTF8-encoded bytes.
   public init?(utf8String bytes: UnsafePointer<CChar>) {
     if let ns = NSString(utf8String: bytes) {
-      self = ns._swiftObject
+      self = String._unconditionallyBridgeFromObjectiveC(ns)
     } else {
       return nil
     }
   }
+}
 
-  //===--- Instance Methods/Properties-------------------------------------===//
-  //===--------------------------------------------------------------------===//
-
-  //===--- Omitted by agreement during API review 5/20/2014 ---------------===//
-  // @property BOOL boolValue;
-
-  // - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding
-
-  /// Returns a Boolean value that indicates whether the
-  /// `String` can be converted to a given encoding without loss of
-  /// information.
-  public func canBeConverted(to encoding: Encoding) -> Bool {
-    return _ns.canBeConverted(to: encoding.rawValue)
-  }
-
-  // @property NSString* capitalizedString
-
-  /// Produce a string with the first character from each word changed
-  /// to the corresponding uppercase value.
-  public var capitalized: String {
-    return _ns.capitalized as String
-  }
-
-  // @property (readonly, copy) NSString *localizedCapitalizedString NS_AVAILABLE(10_11, 9_0);
-
-  /// A capitalized representation of the `String` that is produced
-  /// using the current locale.
-  public var localizedCapitalized: String {
-    return _ns.localizedCapitalized
-  }
-
-  // - (NSString *)capitalizedStringWithLocale:(Locale *)locale
-
-  /// Returns a capitalized representation of the `String`
-  /// using the specified locale.
-  public func capitalized(with locale: Locale?) -> String {
-    return _ns.capitalized(with: locale) as String
-  }
-
-  // - (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
-
-  /// Returns the result of invoking `compare:options:` with
-  /// `NSCaseInsensitiveSearch` as the only option.
-  public func caseInsensitiveCompare(_ aString: String) -> ComparisonResult {
-    return _ns.caseInsensitiveCompare(aString)
-  }
-
-  //===--- Omitted by agreement during API review 5/20/2014 ---------------===//
-  // - (unichar)characterAtIndex:(NSUInteger)index
-  //
-  // We have a different meaning for "Character" in Swift, and we are
-  // trying not to expose error-prone UTF-16 integer indexes
-
-  // - (NSString *)
-  //     commonPrefixWithString:(NSString *)aString
-  //     options:(StringCompareOptions)mask
-
-  /// Returns a string containing characters the `String` and a
-  /// given string have in common, starting from the beginning of each
-  /// up to the first characters that aren't equivalent.
-  public func commonPrefix(
-    with aString: String, options: CompareOptions = []) -> String {
-    return _ns.commonPrefix(with: aString, options: options)
-  }
-
-  // - (NSComparisonResult)
-  //     compare:(NSString *)aString
-  //
-  // - (NSComparisonResult)
-  //     compare:(NSString *)aString options:(StringCompareOptions)mask
-  //
-  // - (NSComparisonResult)
-  //     compare:(NSString *)aString options:(StringCompareOptions)mask
-  //     range:(NSRange)range
-  //
-  // - (NSComparisonResult)
-  //     compare:(NSString *)aString options:(StringCompareOptions)mask
-  //     range:(NSRange)range locale:(id)locale
-
-  /// Compares the string using the specified options and
-  /// returns the lexical ordering for the range.
-  public func compare(
-    _ aString: String,
-    options mask: CompareOptions = [],
-    range: Range<Index>? = nil,
-    locale: Locale? = nil
-  ) -> ComparisonResult {
-    // According to Ali Ozer, there may be some real advantage to
-    // dispatching to the minimal selector for the supplied options.
-    // So let's do that; the switch should compile away anyhow.
-    return locale != nil ? _ns.compare(
-      aString,
-      options: mask,
-      range: _toNSRange(
-        range ?? self.characters.startIndex..<self.characters.endIndex
-      ),
-      locale: locale?._bridgeToObjectiveC()
-    )
-
-    : range != nil ? _ns.compare(
-      aString,
-      options: mask,
-      range: _toNSRange(range!)
-    )
-
-    : !mask.isEmpty ? _ns.compare(aString, options: mask)
-
-    : _ns.compare(aString)
-  }
-
-  // - (NSUInteger)
-  //     completePathIntoString:(NSString **)outputName
-  //     caseSensitive:(BOOL)flag
-  //     matchesIntoArray:(NSArray **)outputArray
-  //     filterTypes:(NSArray *)filterTypes
-
-  /// Interprets the `String` as a path in the file system and
-  /// attempts to perform filename completion, returning a numeric
-  /// value that indicates whether a match was possible, and by
-  /// reference the longest path that matches the `String`.
-  /// Returns the actual number of matching paths.
-  public func completePath(
-    into outputName: UnsafeMutablePointer<String>? = nil,
-    caseSensitive: Bool,
-    matchesInto outputArray: UnsafeMutablePointer<[String]>? = nil,
-    filterTypes: [String]? = nil
-  ) -> Int {
-
-    var outputNamePlaceholder: String?
-    var outputArrayPlaceholder = [String]()
-    let res = self._ns.completePath(
-        into: &outputNamePlaceholder,
-        caseSensitive: caseSensitive,
-        matchesInto: &outputArrayPlaceholder,
-        filterTypes: filterTypes
-    )
-    if let n = outputNamePlaceholder {
-        outputName?.pointee = n
-    } else {
-        outputName?.pointee = ""
-    }
-    outputArray?.pointee = outputArrayPlaceholder
-    return res
-  }
-
-  // - (NSArray *)
-  //     componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
-
-  /// Returns an array containing substrings from the `String`
-  /// that have been divided by characters in a given set.
-  public func components(separatedBy separator: CharacterSet) -> [String] {
-    return _ns.components(separatedBy: separator)
-  }
-
-
-  // - (NSArray *)componentsSeparatedByString:(NSString *)separator
-
-  /// Returns an array containing substrings from the `String`
-  /// that have been divided by a given separator.
-  public func components(separatedBy separator: String) -> [String] {
-    return _ns.components(separatedBy: separator)
-  }
-
-  // - (const char *)cStringUsingEncoding:(NSStringEncoding)encoding
-
-  /// Returns a representation of the `String` as a C string
-  /// using a given encoding.
-  public func cString(using encoding: Encoding) -> [CChar]? {
-    return withExtendedLifetime(_ns) {
-      (s: NSString) -> [CChar]? in
-      _persistCString(s.cString(using: encoding.rawValue))
-    }
-  }
-
-  // - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
-  //
-  // - (NSData *)
-  //     dataUsingEncoding:(NSStringEncoding)encoding
-  //     allowLossyConversion:(BOOL)flag
-
-  /// Returns a `Data` containing a representation of
-  /// the `String` encoded using a given encoding.
-  public func data(
-    using encoding: Encoding,
-    allowLossyConversion: Bool = false
-  ) -> Data? {
-    return _ns.data(
-      using: encoding.rawValue,
-      allowLossyConversion: allowLossyConversion)
-  }
-
-  // @property NSString* decomposedStringWithCanonicalMapping;
-
-  /// Returns a string made by normalizing the `String`'s
-  /// contents using Form D.
-  public var decomposedStringWithCanonicalMapping: String {
-    return _ns.decomposedStringWithCanonicalMapping
-  }
-
-  // @property NSString* decomposedStringWithCompatibilityMapping;
-
-  /// Returns a string made by normalizing the `String`'s
-  /// contents using Form KD.
-  public var decomposedStringWithCompatibilityMapping: String {
-    return _ns.decomposedStringWithCompatibilityMapping
-  }
-
-  //===--- Importing Foundation should not affect String printing ---------===//
-  // Therefore, we're not exposing this:
-  //
-  //   @property NSString* description
-
-
-  //===--- Omitted for consistency with API review results 5/20/2014 -----===//
-  // @property double doubleValue;
-
-  // - (void)
-  //     enumerateLinesUsing:(void (^)(NSString *line, BOOL *stop))block
-
-  /// Enumerates all the lines in a string.
-  public func enumerateLines(
-    invoking body: @escaping (_ line: String, _ stop: inout Bool) -> Void
-  ) {
-    _ns.enumerateLines {
-      (line: String, stop: UnsafeMutablePointer<ObjCBool>)
-    in
-      var stop_ = false
-      body(line, &stop_)
-      if stop_ {
-        stop.pointee = true
-      }
-    }
-  }
-
-
-  // - (void)
-  //     enumerateSubstringsInRange:(NSRange)range
-  //     options:(NSStringEnumerationOptions)opts
-  //     usingBlock:(
-  //       void (^)(
-  //         NSString *substring,
-  //         NSRange substringRange,
-  //         NSRange enclosingRange,
-  //         BOOL *stop)
-  //       )block
-
-  /// Enumerates the substrings of the specified type in the
-  /// specified range of the string.
-  public func enumerateSubstrings(
-    in range: Range<Index>,
-    options opts: EnumerationOptions = [],
-    _ body: @escaping (
-      _ substring: String?, _ substringRange: Range<Index>,
-      _ enclosingRange: Range<Index>, inout Bool
-    ) -> Void
-  ) {
-    _ns.enumerateSubstrings(in: _toNSRange(range), options: opts) {
-      var stop_ = false
-
-      body($0,
-        self._range($1),
-        self._range($2),
-        &stop_)
-
-      if stop_ {
-        UnsafeMutablePointer($3).pointee = true
-      }
-    }
-  }
-
-  // @property NSStringEncoding fastestEncoding;
-
-  /// Returns the fastest encoding to which the `String` may be
-  /// converted without loss of information.
-  public var fastestEncoding: Encoding {
-    return Encoding(rawValue: _ns.fastestEncoding)
-  }
-
-  // - (const char *)fileSystemRepresentation
-
-  /// Returns a file system-specific representation of the `String`.
-  @available(*, unavailable, message: "Use getFileSystemRepresentation on URL instead.")
-  public var fileSystemRepresentation: [CChar] {
-    return _persistCString(_ns.fileSystemRepresentation)!
-  }
-
-  //===--- Omitted for consistency with API review results 5/20/2014 ------===//
-  // @property float floatValue;
-
-  // - (BOOL)
-  //     getBytes:(void *)buffer
-  //     maxLength:(NSUInteger)maxBufferCount
-  //     usedLength:(NSUInteger*)usedBufferCount
-  //     encoding:(NSStringEncoding)encoding
-  //     options:(StringEncodingConversionOptions)options
-  //     range:(NSRange)range
-  //     remainingRange:(NSRangePointer)leftover
-
-  /// Writes the given `range` of characters into `buffer` in a given
-  /// `encoding`, without any allocations.  Does not NULL-terminate.
-  ///
-  /// - Parameter buffer: A buffer into which to store the bytes from
-  ///   the receiver. The returned bytes are not NUL-terminated.
-  ///
-  /// - Parameter maxBufferCount: The maximum number of bytes to write
-  ///   to buffer.
-  ///
-  /// - Parameter usedBufferCount: The number of bytes used from
-  ///   buffer. Pass `nil` if you do not need this value.
-  ///
-  /// - Parameter encoding: The encoding to use for the returned bytes.
-  ///
-  /// - Parameter options: A mask to specify options to use for
-  ///   converting the receiver's contents to `encoding` (if conversion
-  ///   is necessary).
-  ///
-  /// - Parameter range: The range of characters in the receiver to get.
-  ///
-  /// - Parameter leftover: The remaining range. Pass `nil` If you do
-  ///   not need this value.
-  ///
-  /// - Returns: `true` iff some characters were converted.
-  ///
-  /// - Note: Conversion stops when the buffer fills or when the
-  ///   conversion isn't possible due to the chosen encoding.
-  ///
-  /// - Note: will get a maximum of `min(buffer.count, maxLength)` bytes.
-  public func getBytes(
-    _ buffer: inout [UInt8],
-    maxLength maxBufferCount: Int,
-    usedLength usedBufferCount: UnsafeMutablePointer<Int>,
-    encoding: Encoding,
-    options: EncodingConversionOptions = [],
-    range: Range<Index>,
-    remaining leftover: UnsafeMutablePointer<Range<Index>>
-  ) -> Bool {
-    return _withOptionalOutParameter(leftover) {
-      self._ns.getBytes(
-        &buffer,
-        maxLength: min(buffer.count, maxBufferCount),
-        usedLength: usedBufferCount,
-        encoding: encoding.rawValue,
-        options: options,
-        range: _toNSRange(range),
-        remaining: $0)
-    }
-  }
-
-  // - (BOOL)
-  //     getCString:(char *)buffer
-  //     maxLength:(NSUInteger)maxBufferCount
-  //     encoding:(NSStringEncoding)encoding
-
-  /// Converts the `String`'s content to a given encoding and
-  /// stores them in a buffer.
-  /// - Note: will store a maximum of `min(buffer.count, maxLength)` bytes.
-  public func getCString(
-    _ buffer: inout [CChar], maxLength: Int, encoding: Encoding
-  ) -> Bool {
-    return _ns.getCString(&buffer, maxLength: min(buffer.count, maxLength),
-                          encoding: encoding.rawValue)
-  }
-
-  // - (BOOL)
-  //     getFileSystemRepresentation:(char *)buffer
-  //     maxLength:(NSUInteger)maxLength
-
-  /// Interprets the `String` as a system-independent path and
-  /// fills a buffer with a C-string in a format and encoding suitable
-  /// for use with file-system calls.
-  /// - Note: will store a maximum of `min(buffer.count, maxLength)` bytes.
-  @available(*, unavailable, message: "Use getFileSystemRepresentation on URL instead.")
-  public func getFileSystemRepresentation(
-    _ buffer: inout [CChar], maxLength: Int) -> Bool {
-    return _ns.getFileSystemRepresentation(
-      &buffer, maxLength: min(buffer.count, maxLength))
-  }
-
-  // - (void)
-  //     getLineStart:(NSUInteger *)startIndex
-  //     end:(NSUInteger *)lineEndIndex
-  //     contentsEnd:(NSUInteger *)contentsEndIndex
-  //     forRange:(NSRange)aRange
-
-  /// Returns by reference the beginning of the first line and
-  /// the end of the last line touched by the given range.
-  public func getLineStart(
-    _ start: UnsafeMutablePointer<Index>,
-    end: UnsafeMutablePointer<Index>,
-    contentsEnd: UnsafeMutablePointer<Index>,
-    for range: Range<Index>
-  ) {
-    _withOptionalOutParameter(start) {
-      start in self._withOptionalOutParameter(end) {
-        end in self._withOptionalOutParameter(contentsEnd) {
-          contentsEnd in self._ns.getLineStart(
-            start, end: end,
-            contentsEnd: contentsEnd,
-            for: _toNSRange(range))
-        }
-      }
-    }
-  }
-
-  // - (void)
-  //     getParagraphStart:(NSUInteger *)startIndex
-  //     end:(NSUInteger *)endIndex
-  //     contentsEnd:(NSUInteger *)contentsEndIndex
-  //     forRange:(NSRange)aRange
-
-  /// Returns by reference the beginning of the first paragraph
-  /// and the end of the last paragraph touched by the given range.
-  public func getParagraphStart(
-    _ start: UnsafeMutablePointer<Index>,
-    end: UnsafeMutablePointer<Index>,
-    contentsEnd: UnsafeMutablePointer<Index>,
-    for range: Range<Index>
-  ) {
-    _withOptionalOutParameter(start) {
-      start in self._withOptionalOutParameter(end) {
-        end in self._withOptionalOutParameter(contentsEnd) {
-          contentsEnd in self._ns.getParagraphStart(
-            start, end: end,
-            contentsEnd: contentsEnd,
-            for: _toNSRange(range))
-        }
-      }
-    }
-  }
-
-  // - (NSUInteger)hash
-
-  /// An unsigned integer that can be used as a hash table address.
-  public var hash: Int {
-    return _ns.hash
-  }
-
+extension String {
   //===--- Already provided by String's core ------------------------------===//
   // - (instancetype)init
 
@@ -644,13 +181,18 @@
   //     length:(NSUInteger)length
   //     encoding:(NSStringEncoding)encoding
 
-  /// Produces an initialized `NSString` object equivalent to the given
-  /// `bytes` interpreted in the given `encoding`.
+  /// Creates a new string equivalent to the given bytes interpreted in the
+  /// specified encoding.
+  ///
+  /// - Parameters:
+  ///   - bytes: A sequence of bytes to interpret using `encoding`.
+  ///   - encoding: The ecoding to use to interpret `bytes`.
   public init? <S: Sequence>(bytes: S, encoding: Encoding)
     where S.Iterator.Element == UInt8 {
     let byteArray = Array(bytes)
     if let ns = NSString(
       bytes: byteArray, length: byteArray.count, encoding: encoding.rawValue) {
+
       self = String._unconditionallyBridgeFromObjectiveC(ns)
     } else {
       return nil
@@ -663,10 +205,11 @@
   //     encoding:(NSStringEncoding)encoding
   //     freeWhenDone:(BOOL)flag
 
-  /// Produces an initialized `String` object that contains a
-  /// given number of bytes from a given buffer of bytes interpreted
-  /// in a given encoding, and optionally frees the buffer.  WARNING:
-  /// this initializer is not memory-safe!
+  /// Creates a new string that contains the specified number of bytes from the
+  /// given buffer, interpreted in the specified encoding, and optionally
+  /// frees the buffer.
+  ///
+  /// - Warning: This initializer is not memory-safe!
   public init?(
     bytesNoCopy bytes: UnsafeMutableRawPointer, length: Int,
     encoding: Encoding, freeWhenDone flag: Bool
@@ -674,6 +217,7 @@
     if let ns = NSString(
       bytesNoCopy: bytes, length: length, encoding: encoding.rawValue,
       freeWhenDone: flag) {
+
       self = String._unconditionallyBridgeFromObjectiveC(ns)
     } else {
       return nil
@@ -685,9 +229,8 @@
   //     initWithCharacters:(const unichar *)characters
   //     length:(NSUInteger)length
 
-  /// Returns an initialized `String` object that contains a
-  /// given number of characters from a given array of Unicode
-  /// characters.
+  /// Creates a new string that contains the specified number of characters
+  /// from the given C array of Unicode characters.
   public init(
     utf16CodeUnits: UnsafePointer<unichar>,
     count: Int
@@ -700,8 +243,8 @@
   //     length:(NSUInteger)length
   //     freeWhenDone:(BOOL)flag
 
-  /// Returns an initialized `String` object that contains a given
-  /// number of characters from a given array of UTF-16 Code Units
+  /// Creates a new string that contains the specified number of characters
+  /// from the given C array of UTF-16 code units.
   public init(
     utf16CodeUnitsNoCopy: UnsafePointer<unichar>,
     count: Int,
@@ -813,9 +356,9 @@
       return nil
     }
   }
-  
+
   // FIXME: handle optional locale with default arguments
-  
+
   // - (instancetype)
   //     initWithData:(NSData *)data
   //     encoding:(NSStringEncoding)encoding
@@ -826,7 +369,7 @@
     guard let s = NSString(data: data, encoding: encoding.rawValue) else { return nil }
     self = String._unconditionallyBridgeFromObjectiveC(s)
   }
-  
+
   // - (instancetype)initWithFormat:(NSString *)format, ...
 
   /// Returns a `String` object initialized by using a given
@@ -865,83 +408,477 @@
   /// format string as a template into which the remaining argument
   /// values are substituted according to given locale information.
   public init(format: String, locale: Locale?, arguments: [CVarArg]) {
+#if DEPLOYMENT_RUNTIME_SWIFT
     self = withVaList(arguments) {
       String._unconditionallyBridgeFromObjectiveC(
         NSString(format: format, locale: locale?._bridgeToObjectiveC(), arguments: $0)
       )
     }
+#else
+    self = withVaList(arguments) {
+      NSString(format: format, locale: locale, arguments: $0) as String
+    }
+#endif
   }
 
-  //===--- Already provided by core Swift ---------------------------------===//
-  // - (instancetype)initWithString:(NSString *)aString
+}
 
-  //===--- Initializers that can fail dropped for factory functions -------===//
-  // - (instancetype)initWithUTF8String:(const char *)bytes
+extension StringProtocol where Index == String.Index {
+  //===--- Bridging Helpers -----------------------------------------------===//
+  //===--------------------------------------------------------------------===//
 
-  //===--- Omitted for consistency with API review results 5/20/2014 ------===//
-  // @property NSInteger integerValue;
-  // @property Int intValue;
-
-  //===--- Omitted by apparent agreement during API review 5/20/2014 ------===//
-  // @property BOOL absolutePath;
-  // - (BOOL)isEqualToString:(NSString *)aString
-
-  //===--- Kept for consistency with API review results 5/20/2014 ---------===//
-  // We decided to keep pathWithComponents, so keeping this too
-  // @property NSString lastPathComponent;
-
-  /// Returns the last path component of the `String`.
-  @available(*, unavailable, message: "Use lastPathComponent on URL instead.")
-  public var lastPathComponent: String {
-    return _ns.lastPathComponent
+  /// The corresponding `NSString` - a convenience for bridging code.
+  // FIXME(strings): There is probably a better way to bridge Self to NSString
+  var _ns: NSString {
+    return self._ephemeralString._bridgeToObjectiveC()
   }
 
-  //===--- Renamed by agreement during API review 5/20/2014 ---------------===//
-  // @property NSUInteger length;
+  // self can be a Substring so we need to subtract/add this offset when
+  // passing _ns to the Foundation APIs. Will be 0 if self is String.
+  @_inlineable
+  @_versioned
+  internal var _substringOffset: Int {
+    return self.startIndex.encodedOffset
+  }
 
-  /// Returns the number of Unicode characters in the `String`.
-  @available(*, unavailable,
-    message: "Take the count of a UTF-16 view instead, i.e. str.utf16.count")
-  public var utf16Count: Int {
-    return _ns.length
+  /// Return an `Index` corresponding to the given offset in our UTF-16
+  /// representation.
+  func _index(_ utf16Index: Int) -> Index {
+    return Index(encodedOffset: utf16Index + _substringOffset)
+  }
+
+  @_inlineable
+  @_versioned
+  internal func _toRelativeNSRange(_ r: Range<String.Index>) -> NSRange {
+    return NSRange(
+      location: r.lowerBound.encodedOffset - _substringOffset,
+      length: r.upperBound.encodedOffset - r.lowerBound.encodedOffset)
+  }
+
+  /// Return a `Range<Index>` corresponding to the given `NSRange` of
+  /// our UTF-16 representation.
+  func _range(_ r: NSRange) -> Range<Index> {
+    return _index(r.location)..<_index(r.location + r.length)
+  }
+
+  /// Return a `Range<Index>?` corresponding to the given `NSRange` of
+  /// our UTF-16 representation.
+  func _optionalRange(_ r: NSRange) -> Range<Index>? {
+    if r.location == NSNotFound {
+      return nil
+    }
+    return _range(r)
+  }
+
+  /// Invoke `body` on an `Int` buffer.  If `index` was converted from
+  /// non-`nil`, convert the buffer to an `Index` and write it into the
+  /// memory referred to by `index`
+  func _withOptionalOutParameter<Result>(
+    _ index: UnsafeMutablePointer<Index>?,
+    _ body: (UnsafeMutablePointer<Int>?) -> Result
+  ) -> Result {
+    var utf16Index: Int = 0
+    let result = (index != nil ? body(&utf16Index) : body(nil))
+    index?.pointee = _index(utf16Index)
+    return result
+  }
+
+  /// Invoke `body` on an `NSRange` buffer.  If `range` was converted
+  /// from non-`nil`, convert the buffer to a `Range<Index>` and write
+  /// it into the memory referred to by `range`
+  func _withOptionalOutParameter<Result>(
+    _ range: UnsafeMutablePointer<Range<Index>>?,
+    _ body: (UnsafeMutablePointer<NSRange>?) -> Result
+  ) -> Result {
+    var nsRange = NSRange(location: 0, length: 0)
+    let result = (range != nil ? body(&nsRange) : body(nil))
+    range?.pointee = self._range(nsRange)
+    return result
+  }
+
+  //===--- Instance Methods/Properties-------------------------------------===//
+  //===--------------------------------------------------------------------===//
+
+  //===--- Omitted by agreement during API review 5/20/2014 ---------------===//
+  // @property BOOL boolValue;
+
+  // - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding
+
+  /// Returns a Boolean value that indicates whether the string can be
+  /// converted to the specified encoding without loss of information.
+  ///
+  /// - Parameter encoding: A string encoding.
+  /// - Returns: `true` if the string can be encoded in `encoding` without loss
+  ///   of information; otherwise, `false`.
+  public func canBeConverted(to encoding: String.Encoding) -> Bool {
+    return _ns.canBeConverted(to: encoding.rawValue)
+  }
+
+  // @property NSString* capitalizedString
+
+  /// A copy of the string with each word changed to its corresponding
+  /// capitalized spelling.
+  ///
+  /// This property performs the canonical (non-localized) mapping. It is
+  /// suitable for programming operations that require stable results not
+  /// depending on the current locale.
+  ///
+  /// A capitalized string is a string with the first character in each word
+  /// changed to its corresponding uppercase value, and all remaining
+  /// characters set to their corresponding lowercase values. A "word" is any
+  /// sequence of characters delimited by spaces, tabs, or line terminators.
+  /// Some common word delimiting punctuation isn't considered, so this
+  /// property may not generally produce the desired results for multiword
+  /// strings. See the `getLineStart(_:end:contentsEnd:for:)` method for
+  /// additional information.
+  ///
+  /// Case transformations aren’t guaranteed to be symmetrical or to produce
+  /// strings of the same lengths as the originals.
+  public var capitalized: String {
+    return _ns.capitalized as String
+  }
+
+  // @property (readonly, copy) NSString *localizedCapitalizedString NS_AVAILABLE(10_11, 9_0);
+
+  /// A capitalized representation of the string that is produced
+  /// using the current locale.
+  @available(OSX 10.11, iOS 9.0, *)
+  public var localizedCapitalized: String {
+    return _ns.localizedCapitalized
+  }
+
+  // - (NSString *)capitalizedStringWithLocale:(Locale *)locale
+
+  /// Returns a capitalized representation of the string
+  /// using the specified locale.
+  public func capitalized(with locale: Locale?) -> String {
+    return _ns.capitalized(with: locale) as String
+  }
+
+  // - (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
+
+  /// Returns the result of invoking `compare:options:` with
+  /// `NSCaseInsensitiveSearch` as the only option.
+  public func caseInsensitiveCompare<
+    T : StringProtocol
+  >(_ aString: T) -> ComparisonResult {
+    return _ns.caseInsensitiveCompare(aString._ephemeralString)
+  }
+
+  //===--- Omitted by agreement during API review 5/20/2014 ---------------===//
+  // - (unichar)characterAtIndex:(NSUInteger)index
+  //
+  // We have a different meaning for "Character" in Swift, and we are
+  // trying not to expose error-prone UTF-16 integer indexes
+
+  // - (NSString *)
+  //     commonPrefixWithString:(NSString *)aString
+  //     options:(StringCompareOptions)mask
+
+  /// Returns a string containing characters this string and the
+  /// given string have in common, starting from the beginning of each
+  /// up to the first characters that aren't equivalent.
+  public func commonPrefix<
+    T : StringProtocol
+  >(with aString: T, options: String.CompareOptions = []) -> String {
+    return _ns.commonPrefix(with: aString._ephemeralString, options: options)
+  }
+
+  // - (NSComparisonResult)
+  //     compare:(NSString *)aString
+  //
+  // - (NSComparisonResult)
+  //     compare:(NSString *)aString options:(StringCompareOptions)mask
+  //
+  // - (NSComparisonResult)
+  //     compare:(NSString *)aString options:(StringCompareOptions)mask
+  //     range:(NSRange)range
+  //
+  // - (NSComparisonResult)
+  //     compare:(NSString *)aString options:(StringCompareOptions)mask
+  //     range:(NSRange)range locale:(id)locale
+
+  /// Compares the string using the specified options and
+  /// returns the lexical ordering for the range.
+  public func compare<T : StringProtocol>(
+    _ aString: T,
+    options mask: String.CompareOptions = [],
+    range: Range<Index>? = nil,
+    locale: Locale? = nil
+  ) -> ComparisonResult {
+    // According to Ali Ozer, there may be some real advantage to
+    // dispatching to the minimal selector for the supplied options.
+    // So let's do that; the switch should compile away anyhow.
+    let aString = aString._ephemeralString
+    return locale != nil ? _ns.compare(
+      aString,
+      options: mask,
+      range: _toRelativeNSRange(
+        range ?? startIndex..<endIndex
+      ),
+      locale: locale?._bridgeToObjectiveC()
+    )
+
+    : range != nil ? _ns.compare(
+      aString,
+      options: mask,
+      range: _toRelativeNSRange(range!)
+    )
+
+    : !mask.isEmpty ? _ns.compare(aString, options: mask)
+
+    : _ns.compare(aString)
+  }
+
+  // - (NSUInteger)
+  //     completePathIntoString:(NSString **)outputName
+  //     caseSensitive:(BOOL)flag
+  //     matchesIntoArray:(NSArray **)outputArray
+  //     filterTypes:(NSArray *)filterTypes
+
+  /// Interprets the string as a path in the file system and
+  /// attempts to perform filename completion, returning a numeric
+  /// value that indicates whether a match was possible, and by
+  /// reference the longest path that matches the string.
+  ///
+  /// - Returns: The actual number of matching paths.
+  public func completePath(
+    into outputName: UnsafeMutablePointer<String>? = nil,
+    caseSensitive: Bool,
+    matchesInto outputArray: UnsafeMutablePointer<[String]>? = nil,
+    filterTypes: [String]? = nil
+  ) -> Int {
+#if DEPLOYMENT_RUNTIME_SWIFT
+    var outputNamePlaceholder: String?
+    var outputArrayPlaceholder = [String]()
+    let res = self._ns.completePath(
+        into: &outputNamePlaceholder,
+        caseSensitive: caseSensitive,
+        matchesInto: &outputArrayPlaceholder,
+        filterTypes: filterTypes
+    )
+    if let n = outputNamePlaceholder {
+        outputName?.pointee = n
+    } else {
+        outputName?.pointee = ""
+    }
+    outputArray?.pointee = outputArrayPlaceholder
+    return res
+#else // DEPLOYMENT_RUNTIME_SWIFT
+    var nsMatches: NSArray?
+    var nsOutputName: NSString?
+
+    let result: Int = outputName._withNilOrAddress(of: &nsOutputName) {
+      outputName in outputArray._withNilOrAddress(of: &nsMatches) {
+        outputArray in
+        // FIXME: completePath(...) is incorrectly annotated as requiring
+        // non-optional output parameters. rdar://problem/25494184
+        let outputNonOptionalName = unsafeBitCast(
+          outputName, to: AutoreleasingUnsafeMutablePointer<NSString?>.self)
+        let outputNonOptionalArray = unsafeBitCast(
+          outputArray, to: AutoreleasingUnsafeMutablePointer<NSArray?>.self)
+        return self._ns.completePath(
+          into: outputNonOptionalName,
+          caseSensitive: caseSensitive,
+          matchesInto: outputNonOptionalArray,
+          filterTypes: filterTypes
+        )
+      }
+    }
+
+    if let matches = nsMatches {
+      // Since this function is effectively a bridge thunk, use the
+      // bridge thunk semantics for the NSArray conversion
+      outputArray?.pointee = matches as! [String]
+    }
+
+    if let n = nsOutputName {
+      outputName?.pointee = n as String
+    }
+    return result
+#endif // DEPLOYMENT_RUNTIME_SWIFT
+  }
+
+  // - (NSArray *)
+  //     componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
+
+  /// Returns an array containing substrings from the string
+  /// that have been divided by characters in the given set.
+  public func components(separatedBy separator: CharacterSet) -> [String] {
+    return _ns.components(separatedBy: separator)
+  }
+
+  // - (NSArray *)componentsSeparatedByString:(NSString *)separator
+
+  /// Returns an array containing substrings from the string that have been
+  /// divided by the given separator.
+  ///
+  /// The substrings in the resulting array appear in the same order as the
+  /// original string. Adjacent occurrences of the separator string produce
+  /// empty strings in the result. Similarly, if the string begins or ends
+  /// with the separator, the first or last substring, respectively, is empty.
+  /// The following example shows this behavior:
+  ///
+  ///     let list1 = "Karin, Carrie, David"
+  ///     let items1 = list1.components(separatedBy: ", ")
+  ///     // ["Karin", "Carrie", "David"]
+  ///
+  ///     // Beginning with the separator:
+  ///     let list2 = ", Norman, Stanley, Fletcher"
+  ///     let items2 = list2.components(separatedBy: ", ")
+  ///     // ["", "Norman", "Stanley", "Fletcher"
+  ///
+  /// If the list has no separators, the array contains only the original
+  /// string itself.
+  ///
+  ///     let name = "Karin"
+  ///     let list = name.components(separatedBy: ", ")
+  ///     // ["Karin"]
+  ///
+  /// - Parameter separator: The separator string.
+  /// - Returns: An array containing substrings that have been divided from the
+  ///   string using `separator`.
+  // FIXME(strings): now when String conforms to Collection, this can be
+  //   replaced by split(separator:maxSplits:omittingEmptySubsequences:)
+  public func components<
+    T : StringProtocol
+  >(separatedBy separator: T) -> [String] {
+    return _ns.components(separatedBy: separator._ephemeralString)
+  }
+
+  // - (const char *)cStringUsingEncoding:(NSStringEncoding)encoding
+
+  /// Returns a representation of the string as a C string
+  /// using a given encoding.
+  public func cString(using encoding: String.Encoding) -> [CChar]? {
+    return withExtendedLifetime(_ns) {
+      (s: NSString) -> [CChar]? in
+      _persistCString(s.cString(using: encoding.rawValue))
+    }
+  }
+
+  // - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
+  //
+  // - (NSData *)
+  //     dataUsingEncoding:(NSStringEncoding)encoding
+  //     allowLossyConversion:(BOOL)flag
+
+  /// Returns a `Data` containing a representation of
+  /// the `String` encoded using a given encoding.
+  public func data(
+    using encoding: String.Encoding,
+    allowLossyConversion: Bool = false
+  ) -> Data? {
+    return _ns.data(
+      using: encoding.rawValue,
+      allowLossyConversion: allowLossyConversion)
+  }
+
+  // @property NSString* decomposedStringWithCanonicalMapping;
+
+  /// A string created by normalizing the string's contents using Form D.
+  public var decomposedStringWithCanonicalMapping: String {
+    return _ns.decomposedStringWithCanonicalMapping
+  }
+
+  // @property NSString* decomposedStringWithCompatibilityMapping;
+
+  /// A string created by normalizing the string's contents using Form KD.
+  public var decomposedStringWithCompatibilityMapping: String {
+    return _ns.decomposedStringWithCompatibilityMapping
+  }
+
+  //===--- Importing Foundation should not affect String printing ---------===//
+  // Therefore, we're not exposing this:
+  //
+  //   @property NSString* description
+
+
+  //===--- Omitted for consistency with API review results 5/20/2014 -----===//
+  // @property double doubleValue;
+
+  // - (void)
+  //     enumerateLinesUsing:(void (^)(NSString *line, BOOL *stop))block
+
+  /// Enumerates all the lines in a string.
+  public func enumerateLines(
+    invoking body: @escaping (_ line: String, _ stop: inout Bool) -> Void
+  ) {
+    _ns.enumerateLines {
+      (line: String, stop: UnsafeMutablePointer<ObjCBool>)
+    in
+      var stop_ = false
+      body(line, &stop_)
+      if stop_ {
+        stop.pointee = true
+      }
+    }
+  }
+
+  // @property NSStringEncoding fastestEncoding;
+
+  /// The fastest encoding to which the string can be converted without loss
+  /// of information.
+  public var fastestEncoding: String.Encoding {
+    return String.Encoding(rawValue: _ns.fastestEncoding)
+  }
+
+  // - (BOOL)
+  //     getCString:(char *)buffer
+  //     maxLength:(NSUInteger)maxBufferCount
+  //     encoding:(NSStringEncoding)encoding
+
+  /// Converts the `String`'s content to a given encoding and
+  /// stores them in a buffer.
+  /// - Note: will store a maximum of `min(buffer.count, maxLength)` bytes.
+  public func getCString(
+    _ buffer: inout [CChar], maxLength: Int, encoding: String.Encoding
+  ) -> Bool {
+    return _ns.getCString(&buffer,
+                          maxLength: Swift.min(buffer.count, maxLength),
+                          encoding: encoding.rawValue)
+  }
+
+  // - (NSUInteger)hash
+
+  /// An unsigned integer that can be used as a hash table address.
+  public var hash: Int {
+    return _ns.hash
   }
 
   // - (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)enc
 
   /// Returns the number of bytes required to store the
   /// `String` in a given encoding.
-  public func lengthOfBytes(using encoding: Encoding) -> Int {
+  public func lengthOfBytes(using encoding: String.Encoding) -> Int {
     return _ns.lengthOfBytes(using: encoding.rawValue)
   }
 
-  // - (NSRange)lineRangeForRange:(NSRange)aRange
-
-  /// Returns the range of characters representing the line or lines
-  /// containing a given range.
-  public func lineRange(for aRange: Range<Index>) -> Range<Index> {
-    return _range(_ns.lineRange(for: _toNSRange(aRange)))
-  }
-
   // - (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)aString
 
-  /// Compares the string and a given string using a
-  /// case-insensitive, localized, comparison.
+  /// Compares the string and the given string using a case-insensitive,
+  /// localized, comparison.
   public
-  func localizedCaseInsensitiveCompare(_ aString: String) -> ComparisonResult {
-    return _ns.localizedCaseInsensitiveCompare(aString)
+  func localizedCaseInsensitiveCompare<
+    T : StringProtocol
+  >(_ aString: T) -> ComparisonResult {
+    return _ns.localizedCaseInsensitiveCompare(aString._ephemeralString)
   }
 
   // - (NSComparisonResult)localizedCompare:(NSString *)aString
 
-  /// Compares the string and a given string using a localized
-  /// comparison.
-  public func localizedCompare(_ aString: String) -> ComparisonResult {
-    return _ns.localizedCompare(aString)
+  /// Compares the string and the given string using a localized comparison.
+  public func localizedCompare<
+    T : StringProtocol
+  >(_ aString: T) -> ComparisonResult {
+    return _ns.localizedCompare(aString._ephemeralString)
   }
 
-  /// Compares strings as sorted by the Finder.
-  public func localizedStandardCompare(_ string: String) -> ComparisonResult {
-    return _ns.localizedStandardCompare(string)
+  /// Compares the string and the given string as sorted by the Finder.
+  public func localizedStandardCompare<
+    T : StringProtocol
+  >(_ string: T) -> ComparisonResult {
+    return _ns.localizedStandardCompare(string._ephemeralString)
   }
 
   //===--- Omitted for consistency with API review results 5/20/2014 ------===//
@@ -951,6 +888,7 @@
 
   /// A lowercase version of the string that is produced using the current
   /// locale.
+  @available(OSX 10.11, iOS 9.0, *)
   public var localizedLowercase: String {
     return _ns.localizedLowercase
   }
@@ -969,53 +907,25 @@
   /// Returns the maximum number of bytes needed to store the
   /// `String` in a given encoding.
   public
-  func maximumLengthOfBytes(using encoding: Encoding) -> Int {
+  func maximumLengthOfBytes(using encoding: String.Encoding) -> Int {
     return _ns.maximumLengthOfBytes(using: encoding.rawValue)
   }
 
-  // - (NSRange)paragraphRangeForRange:(NSRange)aRange
-
-  /// Returns the range of characters representing the
-  /// paragraph or paragraphs containing a given range.
-  public func paragraphRange(for aRange: Range<Index>) -> Range<Index> {
-    return _range(_ns.paragraphRange(for: _toNSRange(aRange)))
-  }
-
-  // @property NSArray* pathComponents
-
-  /// Returns an array of NSString objects containing, in
-  /// order, each path component of the `String`.
-  @available(*, unavailable, message: "Use pathComponents on URL instead.")
-  public var pathComponents: [String] {
-    return _ns.pathComponents
-  }
-
-  // @property NSString* pathExtension;
-
-  /// Interprets the `String` as a path and returns the
-  /// `String`'s extension, if any.
-  @available(*, unavailable, message: "Use pathExtension on URL instead.")
-  public var pathExtension: String {
-    return _ns.pathExtension
-  }
-
   // @property NSString* precomposedStringWithCanonicalMapping;
 
-  /// Returns a string made by normalizing the `String`'s
-  /// contents using Form C.
+  /// A string created by normalizing the string's contents using Form C.
   public var precomposedStringWithCanonicalMapping: String {
     return _ns.precomposedStringWithCanonicalMapping
   }
 
   // @property NSString * precomposedStringWithCompatibilityMapping;
 
-  /// Returns a string made by normalizing the `String`'s
-  /// contents using Form KC.
+  /// A string created by normalizing the string's contents using Form KC.
   public var precomposedStringWithCompatibilityMapping: String {
     return _ns.precomposedStringWithCompatibilityMapping
   }
 
-#if false
+#if !DEPLOYMENT_RUNTIME_SWIFT
   // - (id)propertyList
 
   /// Parses the `String` as a text representation of a
@@ -1029,151 +939,41 @@
 
   /// Returns a dictionary object initialized with the keys and
   /// values found in the `String`.
-  public
-  func propertyListFromStringsFileFormat() -> [String : String] {
-    return _ns.propertyListFromStringsFileFormat()! as [NSObject : AnyObject]
-      as! [String : String]
+  public func propertyListFromStringsFileFormat() -> [String : String] {
+    return _ns.propertyListFromStringsFileFormat() as! [String : String]? ?? [:]
   }
 #endif
-    
-  // - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)aSet
-  //
-  // - (NSRange)
-  //     rangeOfCharacterFromSet:(NSCharacterSet *)aSet
-  //     options:(StringCompareOptions)mask
-  //
-  // - (NSRange)
-  //     rangeOfCharacterFromSet:(NSCharacterSet *)aSet
-  //     options:(StringCompareOptions)mask
-  //     range:(NSRange)aRange
-
-  /// Finds and returns the range in the `String` of the first
-  /// character from a given character set found in a given range with
-  /// given options.
-  public func rangeOfCharacter(
-    from aSet: CharacterSet,
-    options mask: CompareOptions = [],
-    range aRange: Range<Index>? = nil
-  ) -> Range<Index>? {
-    return _optionalRange(
-      _ns.rangeOfCharacter(
-        from: aSet,
-        options: mask,
-        range: _toNSRange(
-          aRange ?? self.characters.startIndex..<self.characters.endIndex
-        )
-      )
-    )
-  }
-
-  // - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)anIndex
-
-  /// Returns the range in the `String` of the composed
-  /// character sequence located at a given index.
-  public
-  func rangeOfComposedCharacterSequence(at anIndex: Index) -> Range<Index> {
-    return _range(
-      _ns.rangeOfComposedCharacterSequence(at: anIndex.encodedOffset))
-  }
-
-  // - (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range
-
-  /// Returns the range in the string of the composed character
-  /// sequences for a given range.
-  public func rangeOfComposedCharacterSequences(
-    for range: Range<Index>
-  ) -> Range<Index> {
-    // Theoretically, this will be the identity function.  In practice
-    // I think users will be able to observe differences in the input
-    // and output ranges due (if nothing else) to locale changes
-    return _range(
-      _ns.rangeOfComposedCharacterSequences(for: _toNSRange(range)))
-  }
-
-  // - (NSRange)rangeOfString:(NSString *)aString
-  //
-  // - (NSRange)
-  //     rangeOfString:(NSString *)aString options:(StringCompareOptions)mask
-  //
-  // - (NSRange)
-  //     rangeOfString:(NSString *)aString
-  //     options:(StringCompareOptions)mask
-  //     range:(NSRange)aRange
-  //
-  // - (NSRange)
-  //     rangeOfString:(NSString *)aString
-  //     options:(StringCompareOptions)mask
-  //     range:(NSRange)searchRange
-  //     locale:(Locale *)locale
-
-  /// Finds and returns the range of the first occurrence of a
-  /// given string within a given range of the `String`, subject to
-  /// given options, using the specified locale, if any.
-  public func range(
-    of aString: String,
-    options mask: CompareOptions = [],
-    range searchRange: Range<Index>? = nil,
-    locale: Locale? = nil
-  ) -> Range<Index>? {
-    return _optionalRange(
-      locale != nil ? _ns.range(
-        of: aString,
-        options: mask,
-        range: _toNSRange(
-          searchRange ?? self.characters.startIndex..<self.characters.endIndex
-        ),
-        locale: locale
-      )
-      : searchRange != nil ? _ns.range(
-        of: aString, options: mask, range: _toNSRange(searchRange!)
-      )
-      : !mask.isEmpty ? _ns.range(of: aString, options: mask)
-      : _ns.range(of: aString)
-    )
-  }
 
   // - (BOOL)localizedStandardContainsString:(NSString *)str NS_AVAILABLE(10_11, 9_0);
 
-  /// Returns `true` if `self` contains `string`, taking the current locale
-  /// into account.
+  /// Returns a Boolean value indicating whether the string contains the given
+  /// string, taking the current locale into account.
   ///
   /// This is the most appropriate method for doing user-level string searches,
   /// similar to how searches are done generally in the system.  The search is
   /// locale-aware, case and diacritic insensitive.  The exact list of search
   /// options applied may change over time.
-  public func localizedStandardContains(_ string: String) -> Bool {
-    return _ns.localizedStandardContains(string)
-  }
-
-  // - (NSRange)localizedStandardRangeOfString:(NSString *)str NS_AVAILABLE(10_11, 9_0);
-
-  /// Finds and returns the range of the first occurrence of a given string,
-  /// taking the current locale into account.  Returns `nil` if the string was
-  /// not found.
-  ///
-  /// This is the most appropriate method for doing user-level string searches,
-  /// similar to how searches are done generally in the system.  The search is
-  /// locale-aware, case and diacritic insensitive.  The exact list of search
-  /// options applied may change over time.
-  public func localizedStandardRange(of string: String) -> Range<Index>? {
-    return _optionalRange(_ns.localizedStandardRange(of: string))
+  @available(OSX 10.11, iOS 9.0, *)
+  public func localizedStandardContains<
+    T : StringProtocol
+  >(_ string: T) -> Bool {
+    return _ns.localizedStandardContains(string._ephemeralString)
   }
 
   // @property NSStringEncoding smallestEncoding;
 
-  /// Returns the smallest encoding to which the `String` can
-  /// be converted without loss of information.
-  public var smallestEncoding: Encoding {
-    return Encoding(rawValue: _ns.smallestEncoding)
+  /// The smallest encoding to which the string can be converted without
+  /// loss of information.
+  public var smallestEncoding: String.Encoding {
+    return String.Encoding(rawValue: _ns.smallestEncoding)
   }
 
   // - (NSString *)
   //     stringByAddingPercentEncodingWithAllowedCharacters:
   //       (NSCharacterSet *)allowedCharacters
 
-  /// Returns a new string made from the `String` by replacing
-  /// all characters not in the specified set with percent encoded
-  /// characters.
+  /// Returns a new string created by replacing all characters in the string
+  /// not in the specified set with percent encoded characters.
   public func addingPercentEncoding(
     withAllowedCharacters allowedCharacters: CharacterSet
   ) -> String? {
@@ -1193,90 +993,31 @@
 
   // - (NSString *)stringByAppendingFormat:(NSString *)format, ...
 
-  /// Returns a string made by appending to the `String` a
-  /// string constructed from a given format string and the following
-  /// arguments.
-  public func appendingFormat(
-    _ format: String, _ arguments: CVarArg...
+  /// Returns a string created by appending a string constructed from a given
+  /// format string and the following arguments.
+  public func appendingFormat<
+    T : StringProtocol
+  >(
+    _ format: T, _ arguments: CVarArg...
   ) -> String {
     return _ns.appending(
-      String(format: format, arguments: arguments))
-  }
-
-  // - (NSString *)stringByAppendingPathComponent:(NSString *)aString
-
-  /// Returns a new string made by appending to the `String` a given string.
-  @available(*, unavailable, message: "Use appendingPathComponent on URL instead.")
-  public func appendingPathComponent(_ aString: String) -> String {
-    return _ns.appendingPathComponent(aString)
-  }
-
-  // - (NSString *)stringByAppendingPathExtension:(NSString *)ext
-
-  /// Returns a new string made by appending to the `String` an
-  /// extension separator followed by a given extension.
-  @available(*, unavailable, message: "Use appendingPathExtension on URL instead.")
-  public func appendingPathExtension(_ ext: String) -> String? {
-    // FIXME: This method can return nil in practice, for example when self is
-    // an empty string.  OTOH, this is not documented, documentation says that
-    // it always returns a string.
-    //
-    // <rdar://problem/17902469> -[NSString stringByAppendingPathExtension] can
-    // return nil
-    return _ns.appendingPathExtension(ext)
+      String(format: format._ephemeralString, arguments: arguments))
   }
 
   // - (NSString *)stringByAppendingString:(NSString *)aString
 
-  /// Returns a new string made by appending a given string to
-  /// the `String`.
-  public func appending(_ aString: String) -> String {
-    return _ns.appending(aString)
-  }
-
-  // @property NSString* stringByDeletingLastPathComponent;
-
-  /// Returns a new string made by deleting the last path
-  /// component from the `String`, along with any final path
-  /// separator.
-  @available(*, unavailable, message: "Use deletingLastPathComponent on URL instead.")
-  public var deletingLastPathComponent: String {
-    return _ns.deletingLastPathComponent
-  }
-
-  // @property NSString* stringByDeletingPathExtension;
-
-  /// Returns a new string made by deleting the extension (if
-  /// any, and only the last) from the `String`.
-  @available(*, unavailable, message: "Use deletingPathExtension on URL instead.")
-  public var deletingPathExtension: String {
-    return _ns.deletingPathExtension
-  }
-
-  // @property NSString* stringByExpandingTildeInPath;
-
-  /// Returns a new string made by expanding the initial
-  /// component of the `String` to its full path value.
-  @available(*, unavailable, message: "Use expandingTildeInPath on NSString instead.")
-  public var expandingTildeInPath: String {
-    return _ns.expandingTildeInPath
-  }
-
-  // - (NSString *)
-  //     stringByFoldingWithOptions:(StringCompareOptions)options
-  //     locale:(Locale *)locale
-
-  @available(*, unavailable, renamed: "folding(options:locale:)")
-  public func folding(
-    _ options: CompareOptions = [], locale: Locale?
-  ) -> String {
-    return folding(options: options, locale: locale)
+  /// Returns a new string created by appending the given string.
+  // FIXME(strings): shouldn't it be deprecated in favor of `+`?
+  public func appending<
+    T : StringProtocol
+  >(_ aString: T) -> String {
+    return _ns.appending(aString._ephemeralString)
   }
 
   /// Returns a string with the given character folding options
   /// applied.
   public func folding(
-    options: CompareOptions = [], locale: Locale?
+    options: String.CompareOptions = [], locale: Locale?
   ) -> String {
     return _ns.folding(options: options, locale: locale)
   }
@@ -1288,20 +1029,23 @@
   /// Returns a new string formed from the `String` by either
   /// removing characters from the end, or by appending as many
   /// occurrences as necessary of a given pad string.
-  public func padding(
+  public func padding<
+    T : StringProtocol
+  >(
     toLength newLength: Int,
-    withPad padString: String,
+    withPad padString: T,
     startingAt padIndex: Int
   ) -> String {
     return _ns.padding(
-      toLength: newLength, withPad: padString, startingAt: padIndex)
+      toLength: newLength,
+      withPad: padString._ephemeralString,
+      startingAt: padIndex)
   }
 
   // @property NSString* stringByRemovingPercentEncoding;
 
-  /// Returns a new string made from the `String` by replacing
-  /// all percent encoded sequences with the matching UTF-8
-  /// characters.
+  /// A new string made from the string by replacing all percent encoded
+  /// sequences with the matching UTF-8 characters.
   public var removingPercentEncoding: String? {
     return _ns.removingPercentEncoding
   }
@@ -1312,10 +1056,12 @@
 
   /// Returns a new string in which the characters in a
   /// specified range of the `String` are replaced by a given string.
-  public func replacingCharacters(
-    in range: Range<Index>, with replacement: String
-  ) -> String {
-    return _ns.replacingCharacters(in: _toNSRange(range), with: replacement)
+  public func replacingCharacters<
+    T : StringProtocol, R : RangeExpression
+  >(in range: R, with replacement: T) -> String where R.Bound == Index {
+    return _ns.replacingCharacters(
+      in: _toRelativeNSRange(range.relative(to: self)),
+      with: replacement._ephemeralString)
   }
 
   // - (NSString *)
@@ -1329,43 +1075,46 @@
   //     range:(NSRange)searchRange
 
   /// Returns a new string in which all occurrences of a target
-  /// string in a specified range of the `String` are replaced by
+  /// string in a specified range of the string are replaced by
   /// another given string.
-  public func replacingOccurrences(
-    of target: String,
-    with replacement: String,
-    options: CompareOptions = [],
+  public func replacingOccurrences<
+    Target : StringProtocol,
+    Replacement : StringProtocol
+  >(
+    of target: Target,
+    with replacement: Replacement,
+    options: String.CompareOptions = [],
     range searchRange: Range<Index>? = nil
   ) -> String {
+    let target = target._ephemeralString
+    let replacement = replacement._ephemeralString
     return (searchRange != nil) || (!options.isEmpty)
     ? _ns.replacingOccurrences(
       of: target,
       with: replacement,
       options: options,
-      range: _toNSRange(
-        searchRange ?? self.characters.startIndex..<self.characters.endIndex
+      range: _toRelativeNSRange(
+        searchRange ?? startIndex..<endIndex
       )
     )
     : _ns.replacingOccurrences(of: target, with: replacement)
   }
 
-  // @property NSString* stringByResolvingSymlinksInPath;
+#if !DEPLOYMENT_RUNTIME_SWIFT
+  // - (NSString *)
+  //     stringByReplacingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
 
-  /// Returns a new string made from the `String` by resolving
-  /// all symbolic links and standardizing path.
-  @available(*, unavailable, message: "Use resolvingSymlinksInPath on URL instead.")
-  public var resolvingSymlinksInPath: String {
-    return _ns.resolvingSymlinksInPath
+  /// Returns a new string made by replacing in the `String`
+  /// all percent escapes with the matching characters as determined
+  /// by a given encoding.
+  @available(swift, deprecated: 3.0, obsoleted: 4.0,
+    message: "Use removingPercentEncoding instead, which always uses the recommended UTF-8 encoding.")
+  public func replacingPercentEscapes(
+    using encoding: String.Encoding
+  ) -> String? {
+    return _ns.replacingPercentEscapes(using: encoding.rawValue)
   }
-
-  // @property NSString* stringByStandardizingPath;
-
-  /// Returns a new string made by removing extraneous path
-  /// components from the `String`.
-  @available(*, unavailable, message: "Use standardizingPath on URL instead.")
-  public var standardizingPath: String {
-    return _ns.standardizingPath
-  }
+#endif
 
   // - (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set
 
@@ -1375,43 +1124,11 @@
     return _ns.trimmingCharacters(in: set)
   }
 
-  // - (NSArray *)stringsByAppendingPaths:(NSArray *)paths
-
-  /// Returns an array of strings made by separately appending
-  /// to the `String` each string in a given array.
-  @available(*, unavailable, message: "Map over paths with appendingPathComponent instead.")
-  public func strings(byAppendingPaths paths: [String]) -> [String] {
-    fatalError("This function is not available")
-  }
-
-  // - (NSString *)substringFromIndex:(NSUInteger)anIndex
-
-  /// Returns a new string containing the characters of the
-  /// `String` from the one at a given index to the end.
-  public func substring(from index: Index) -> String {
-    return _ns.substring(from: index.encodedOffset)
-  }
-
-  // - (NSString *)substringToIndex:(NSUInteger)anIndex
-
-  /// Returns a new string containing the characters of the
-  /// `String` up to, but not including, the one at a given index.
-  public func substring(to index: Index) -> String {
-    return _ns.substring(to: index.encodedOffset)
-  }
-
-  // - (NSString *)substringWithRange:(NSRange)aRange
-
-  /// Returns a string object containing the characters of the
-  /// `String` that lie within a given range.
-  public func substring(with aRange: Range<Index>) -> String {
-    return _ns.substring(with: _toNSRange(aRange))
-  }
-
   // @property (readonly, copy) NSString *localizedUppercaseString NS_AVAILABLE(10_11, 9_0);
 
   /// An uppercase version of the string that is produced using the current
   /// locale.
+  @available(OSX 10.11, iOS 9.0, *)
   public var localizedUppercase: String {
     return _ns.localizedUppercase as String
   }
@@ -1436,12 +1153,16 @@
 
   /// Writes the contents of the `String` to a file at a given
   /// path using a given encoding.
-  public func write(
-    toFile path: String, atomically useAuxiliaryFile:Bool,
-    encoding enc: Encoding
+  public func write<
+    T : StringProtocol
+  >(
+    toFile path: T, atomically useAuxiliaryFile: Bool,
+    encoding enc: String.Encoding
   ) throws {
-    try self._ns.write(
-      toFile: path, atomically: useAuxiliaryFile, encoding: enc.rawValue)
+    try _ns.write(
+      toFile: path._ephemeralString,
+      atomically: useAuxiliaryFile,
+      encoding: enc.rawValue)
   }
 
   // - (BOOL)
@@ -1454,23 +1175,459 @@
   /// by url using the specified encoding.
   public func write(
     to url: URL, atomically useAuxiliaryFile: Bool,
-    encoding enc: Encoding
+    encoding enc: String.Encoding
   ) throws {
-    try self._ns.write(
+    try _ns.write(
       to: url, atomically: useAuxiliaryFile, encoding: enc.rawValue)
   }
 
   // - (nullable NSString *)stringByApplyingTransform:(NSString *)transform reverse:(BOOL)reverse NS_AVAILABLE(10_11, 9_0);
 
+#if !DEPLOYMENT_RUNTIME_SWIFT
   /// Perform string transliteration.
-#if false
+  @available(OSX 10.11, iOS 9.0, *)
   public func applyingTransform(
     _ transform: StringTransform, reverse: Bool
   ) -> String? {
     return _ns.applyingTransform(transform, reverse: reverse)
   }
+
+  // - (void)
+  //     enumerateLinguisticTagsInRange:(NSRange)range
+  //     scheme:(NSString *)tagScheme
+  //     options:(LinguisticTaggerOptions)opts
+  //     orthography:(Orthography *)orthography
+  //     usingBlock:(
+  //       void (^)(
+  //         NSString *tag, NSRange tokenRange,
+  //         NSRange sentenceRange, BOOL *stop)
+  //       )block
+
+  /// Performs linguistic analysis on the specified string by
+  /// enumerating the specific range of the string, providing the
+  /// Block with the located tags.
+  public func enumerateLinguisticTags<
+    T : StringProtocol, R : RangeExpression
+  >(
+    in range: R,
+    scheme tagScheme: T,
+    options opts: NSLinguisticTagger.Options = [],
+    orthography: NSOrthography? = nil,
+    invoking body:
+      (String, Range<Index>, Range<Index>, inout Bool) -> Void
+  ) where R.Bound == Index {
+    let range = range.relative(to: self)
+    _ns.enumerateLinguisticTags(
+      in: _toRelativeNSRange(range),
+      scheme: tagScheme._ephemeralString,
+      options: opts,
+      orthography: orthography != nil ? orthography! : nil
+    ) {
+      var stop_ = false
+      body($0, self._range($1), self._range($2), &stop_)
+      if stop_ {
+        $3.pointee = true
+      }
+    }
+  }
 #endif
-    
+
+  // - (void)
+  //     enumerateSubstringsInRange:(NSRange)range
+  //     options:(NSStringEnumerationOptions)opts
+  //     usingBlock:(
+  //       void (^)(
+  //         NSString *substring,
+  //         NSRange substringRange,
+  //         NSRange enclosingRange,
+  //         BOOL *stop)
+  //       )block
+
+  /// Enumerates the substrings of the specified type in the specified range of
+  /// the string.
+  ///
+  /// Mutation of a string value while enumerating its substrings is not
+  /// supported. If you need to mutate a string from within `body`, convert
+  /// your string to an `NSMutableString` instance and then call the
+  /// `enumerateSubstrings(in:options:using:)` method.
+  ///
+  /// - Parameters:
+  ///   - range: The range within the string to enumerate substrings.
+  ///   - opts: Options specifying types of substrings and enumeration styles.
+  ///     If `opts` is omitted or empty, `body` is called a single time with
+  ///     the range of the string specified by `range`.
+  ///   - body: The closure executed for each substring in the enumeration. The
+  ///     closure takes four arguments:
+  ///     - The enumerated substring. If `substringNotRequired` is included in
+  ///       `opts`, this parameter is `nil` for every execution of the
+  ///       closure.
+  ///     - The range of the enumerated substring in the string that
+  ///       `enumerate(in:options:_:)` was called on.
+  ///     - The range that includes the substring as well as any separator or
+  ///       filler characters that follow. For instance, for lines,
+  ///       `enclosingRange` contains the line terminators. The enclosing
+  ///       range for the first string enumerated also contains any characters
+  ///       that occur before the string. Consecutive enclosing ranges are
+  ///       guaranteed not to overlap, and every single character in the
+  ///       enumerated range is included in one and only one enclosing range.
+  ///     - An `inout` Boolean value that the closure can use to stop the
+  ///       enumeration by setting `stop = true`.
+  public func enumerateSubstrings<
+    R : RangeExpression
+  >(
+    in range: R,
+    options opts: String.EnumerationOptions = [],
+    _ body: @escaping (
+      _ substring: String?, _ substringRange: Range<Index>,
+      _ enclosingRange: Range<Index>, inout Bool
+    ) -> Void
+  ) where R.Bound == Index {
+    _ns.enumerateSubstrings(
+      in: _toRelativeNSRange(range.relative(to: self)), options: opts) {
+      var stop_ = false
+
+      body($0,
+        self._range($1),
+        self._range($2),
+        &stop_)
+
+      if stop_ {
+        UnsafeMutablePointer($3).pointee = true
+      }
+    }
+  }
+
+  //===--- Omitted for consistency with API review results 5/20/2014 ------===//
+  // @property float floatValue;
+
+  // - (BOOL)
+  //     getBytes:(void *)buffer
+  //     maxLength:(NSUInteger)maxBufferCount
+  //     usedLength:(NSUInteger*)usedBufferCount
+  //     encoding:(NSStringEncoding)encoding
+  //     options:(StringEncodingConversionOptions)options
+  //     range:(NSRange)range
+  //     remainingRange:(NSRangePointer)leftover
+
+  /// Writes the given `range` of characters into `buffer` in a given
+  /// `encoding`, without any allocations.  Does not NULL-terminate.
+  ///
+  /// - Parameter buffer: A buffer into which to store the bytes from
+  ///   the receiver. The returned bytes are not NUL-terminated.
+  ///
+  /// - Parameter maxBufferCount: The maximum number of bytes to write
+  ///   to buffer.
+  ///
+  /// - Parameter usedBufferCount: The number of bytes used from
+  ///   buffer. Pass `nil` if you do not need this value.
+  ///
+  /// - Parameter encoding: The encoding to use for the returned bytes.
+  ///
+  /// - Parameter options: A mask to specify options to use for
+  ///   converting the receiver's contents to `encoding` (if conversion
+  ///   is necessary).
+  ///
+  /// - Parameter range: The range of characters in the receiver to get.
+  ///
+  /// - Parameter leftover: The remaining range. Pass `nil` If you do
+  ///   not need this value.
+  ///
+  /// - Returns: `true` iff some characters were converted.
+  ///
+  /// - Note: Conversion stops when the buffer fills or when the
+  ///   conversion isn't possible due to the chosen encoding.
+  ///
+  /// - Note: will get a maximum of `min(buffer.count, maxLength)` bytes.
+  public func getBytes<
+    R : RangeExpression
+  >(
+    _ buffer: inout [UInt8],
+    maxLength maxBufferCount: Int,
+    usedLength usedBufferCount: UnsafeMutablePointer<Int>,
+    encoding: String.Encoding,
+    options: String.EncodingConversionOptions = [],
+    range: R,
+    remaining leftover: UnsafeMutablePointer<Range<Index>>
+  ) -> Bool where R.Bound == Index {
+    return _withOptionalOutParameter(leftover) {
+      self._ns.getBytes(
+        &buffer,
+        maxLength: Swift.min(buffer.count, maxBufferCount),
+        usedLength: usedBufferCount,
+        encoding: encoding.rawValue,
+        options: options,
+        range: _toRelativeNSRange(range.relative(to: self)),
+        remaining: $0)
+    }
+  }
+
+  // - (void)
+  //     getLineStart:(NSUInteger *)startIndex
+  //     end:(NSUInteger *)lineEndIndex
+  //     contentsEnd:(NSUInteger *)contentsEndIndex
+  //     forRange:(NSRange)aRange
+
+  /// Returns by reference the beginning of the first line and
+  /// the end of the last line touched by the given range.
+  public func getLineStart<
+    R : RangeExpression
+  >(
+    _ start: UnsafeMutablePointer<Index>,
+    end: UnsafeMutablePointer<Index>,
+    contentsEnd: UnsafeMutablePointer<Index>,
+    for range: R
+  ) where R.Bound == Index {
+    _withOptionalOutParameter(start) {
+      start in self._withOptionalOutParameter(end) {
+        end in self._withOptionalOutParameter(contentsEnd) {
+          contentsEnd in self._ns.getLineStart(
+            start, end: end,
+            contentsEnd: contentsEnd,
+            for: _toRelativeNSRange(range.relative(to: self)))
+        }
+      }
+    }
+  }
+
+  // - (void)
+  //     getParagraphStart:(NSUInteger *)startIndex
+  //     end:(NSUInteger *)endIndex
+  //     contentsEnd:(NSUInteger *)contentsEndIndex
+  //     forRange:(NSRange)aRange
+
+  /// Returns by reference the beginning of the first paragraph
+  /// and the end of the last paragraph touched by the given range.
+  public func getParagraphStart<
+    R : RangeExpression
+  >(
+    _ start: UnsafeMutablePointer<Index>,
+    end: UnsafeMutablePointer<Index>,
+    contentsEnd: UnsafeMutablePointer<Index>,
+    for range: R
+  ) where R.Bound == Index {
+    _withOptionalOutParameter(start) {
+      start in self._withOptionalOutParameter(end) {
+        end in self._withOptionalOutParameter(contentsEnd) {
+          contentsEnd in self._ns.getParagraphStart(
+            start, end: end,
+            contentsEnd: contentsEnd,
+            for: _toRelativeNSRange(range.relative(to: self)))
+        }
+      }
+    }
+  }
+
+  //===--- Already provided by core Swift ---------------------------------===//
+  // - (instancetype)initWithString:(NSString *)aString
+
+  //===--- Initializers that can fail dropped for factory functions -------===//
+  // - (instancetype)initWithUTF8String:(const char *)bytes
+
+  //===--- Omitted for consistency with API review results 5/20/2014 ------===//
+  // @property NSInteger integerValue;
+  // @property Int intValue;
+
+  //===--- Omitted by apparent agreement during API review 5/20/2014 ------===//
+  // @property BOOL absolutePath;
+  // - (BOOL)isEqualToString:(NSString *)aString
+
+  // - (NSRange)lineRangeForRange:(NSRange)aRange
+
+  /// Returns the range of characters representing the line or lines
+  /// containing a given range.
+  public func lineRange<
+    R : RangeExpression
+  >(for aRange: R) -> Range<Index> where R.Bound == Index {
+    return _range(_ns.lineRange(
+      for: _toRelativeNSRange(aRange.relative(to: self))))
+  }
+
+#if !DEPLOYMENT_RUNTIME_SWIFT
+  // - (NSArray *)
+  //     linguisticTagsInRange:(NSRange)range
+  //     scheme:(NSString *)tagScheme
+  //     options:(LinguisticTaggerOptions)opts
+  //     orthography:(Orthography *)orthography
+  //     tokenRanges:(NSArray**)tokenRanges
+
+  /// Returns an array of linguistic tags for the specified
+  /// range and requested tags within the receiving string.
+  public func linguisticTags<
+    T : StringProtocol, R : RangeExpression
+  >(
+    in range: R,
+    scheme tagScheme: T,
+    options opts: NSLinguisticTagger.Options = [],
+    orthography: NSOrthography? = nil,
+    tokenRanges: UnsafeMutablePointer<[Range<Index>]>? = nil // FIXME:Can this be nil?
+  ) -> [String] where R.Bound == Index {
+    var nsTokenRanges: NSArray?
+    let result = tokenRanges._withNilOrAddress(of: &nsTokenRanges) {
+      self._ns.linguisticTags(
+        in: _toRelativeNSRange(range.relative(to: self)),
+        scheme: tagScheme._ephemeralString,
+        options: opts,
+        orthography: orthography,
+        tokenRanges: $0) as NSArray
+    }
+
+    if nsTokenRanges != nil {
+      tokenRanges?.pointee = (nsTokenRanges! as [AnyObject]).map {
+        self._range($0.rangeValue)
+      }
+    }
+
+    return result as! [String]
+  }
+
+  // - (NSRange)paragraphRangeForRange:(NSRange)aRange
+
+  /// Returns the range of characters representing the
+  /// paragraph or paragraphs containing a given range.
+  public func paragraphRange<
+    R : RangeExpression
+  >(for aRange: R) -> Range<Index> where R.Bound == Index {
+    return _range(
+      _ns.paragraphRange(for: _toRelativeNSRange(aRange.relative(to: self))))
+  }
+#endif
+
+  // - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)aSet
+  //
+  // - (NSRange)
+  //     rangeOfCharacterFromSet:(NSCharacterSet *)aSet
+  //     options:(StringCompareOptions)mask
+  //
+  // - (NSRange)
+  //     rangeOfCharacterFromSet:(NSCharacterSet *)aSet
+  //     options:(StringCompareOptions)mask
+  //     range:(NSRange)aRange
+
+  /// Finds and returns the range in the `String` of the first
+  /// character from a given character set found in a given range with
+  /// given options.
+  public func rangeOfCharacter(
+    from aSet: CharacterSet,
+    options mask: String.CompareOptions = [],
+    range aRange: Range<Index>? = nil
+  ) -> Range<Index>? {
+    return _optionalRange(
+      _ns.rangeOfCharacter(
+        from: aSet,
+        options: mask,
+        range: _toRelativeNSRange(
+          aRange ?? startIndex..<endIndex
+        )
+      )
+    )
+  }
+
+  // - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)anIndex
+
+  /// Returns the range in the `String` of the composed
+  /// character sequence located at a given index.
+  public
+  func rangeOfComposedCharacterSequence(at anIndex: Index) -> Range<Index> {
+    return _range(
+      _ns.rangeOfComposedCharacterSequence(at: anIndex.encodedOffset))
+  }
+
+  // - (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range
+
+  /// Returns the range in the string of the composed character
+  /// sequences for a given range.
+  public func rangeOfComposedCharacterSequences<
+    R : RangeExpression
+  >(
+    for range: R
+  ) -> Range<Index> where R.Bound == Index {
+    // Theoretically, this will be the identity function.  In practice
+    // I think users will be able to observe differences in the input
+    // and output ranges due (if nothing else) to locale changes
+    return _range(
+      _ns.rangeOfComposedCharacterSequences(
+        for: _toRelativeNSRange(range.relative(to: self))))
+  }
+
+  // - (NSRange)rangeOfString:(NSString *)aString
+  //
+  // - (NSRange)
+  //     rangeOfString:(NSString *)aString options:(StringCompareOptions)mask
+  //
+  // - (NSRange)
+  //     rangeOfString:(NSString *)aString
+  //     options:(StringCompareOptions)mask
+  //     range:(NSRange)aRange
+  //
+  // - (NSRange)
+  //     rangeOfString:(NSString *)aString
+  //     options:(StringCompareOptions)mask
+  //     range:(NSRange)searchRange
+  //     locale:(Locale *)locale
+
+  /// Finds and returns the range of the first occurrence of a
+  /// given string within a given range of the `String`, subject to
+  /// given options, using the specified locale, if any.
+  public func range<
+    T : StringProtocol
+  >(
+    of aString: T,
+    options mask: String.CompareOptions = [],
+    range searchRange: Range<Index>? = nil,
+    locale: Locale? = nil
+  ) -> Range<Index>? {
+    let aString = aString._ephemeralString
+    return _optionalRange(
+      locale != nil ? _ns.range(
+        of: aString,
+        options: mask,
+        range: _toRelativeNSRange(
+          searchRange ?? startIndex..<endIndex
+        ),
+        locale: locale
+      )
+      : searchRange != nil ? _ns.range(
+        of: aString, options: mask, range: _toRelativeNSRange(searchRange!)
+      )
+      : !mask.isEmpty ? _ns.range(of: aString, options: mask)
+      : _ns.range(of: aString)
+    )
+  }
+
+  // - (NSRange)localizedStandardRangeOfString:(NSString *)str NS_AVAILABLE(10_11, 9_0);
+
+  /// Finds and returns the range of the first occurrence of a given string,
+  /// taking the current locale into account.  Returns `nil` if the string was
+  /// not found.
+  ///
+  /// This is the most appropriate method for doing user-level string searches,
+  /// similar to how searches are done generally in the system.  The search is
+  /// locale-aware, case and diacritic insensitive.  The exact list of search
+  /// options applied may change over time.
+  @available(OSX 10.11, iOS 9.0, *)
+  public func localizedStandardRange<
+    T : StringProtocol
+  >(of string: T) -> Range<Index>? {
+    return _optionalRange(
+      _ns.localizedStandardRange(of: string._ephemeralString))
+  }
+
+#if !DEPLOYMENT_RUNTIME_SWIFT
+  // - (NSString *)
+  //     stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
+
+  /// Returns a representation of the `String` using a given
+  /// encoding to determine the percent escapes necessary to convert
+  /// the `String` into a legal URL string.
+  @available(swift, deprecated: 3.0, obsoleted: 4.0,
+    message: "Use addingPercentEncoding(withAllowedCharacters:) instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent since each URL component or subcomponent has different rules for what characters are valid.")
+  public func addingPercentEscapes(
+    using encoding: String.Encoding
+  ) -> String? {
+    return _ns.addingPercentEscapes(using: encoding.rawValue)
+  }
+#endif
+
   //===--- From the 10.10 release notes; not in public documentation ------===//
   // No need to make these unavailable on earlier OSes, since they can
   // forward trivially to rangeOfString.
@@ -1479,44 +1636,233 @@
   /// `self` by case-sensitive, non-literal search.
   ///
   /// Equivalent to `self.rangeOfString(other) != nil`
-  public func contains(_ other: String) -> Bool {
+  public func contains<T : StringProtocol>(_ other: T) -> Bool {
     let r = self.range(of: other) != nil
     if #available(OSX 10.10, iOS 8.0, *) {
-      _sanityCheck(r == _ns.contains(other))
+      _sanityCheck(r == _ns.contains(other._ephemeralString))
     }
     return r
   }
-  
-  /// Returns `true` iff `other` is non-empty and contained within
-  /// `self` by case-insensitive, non-literal search, taking into
-  /// account the current locale.
+
+  /// Returns a Boolean value indicating whether the given string is non-empty
+  /// and contained within this string by case-insensitive, non-literal
+  /// search, taking into account the current locale.
   ///
-  /// Locale-independent case-insensitive operation, and other needs,
-  /// can be achieved by calling
-  /// `rangeOfString(_:options:_, range:_locale:_)`.
+  /// Locale-independent case-insensitive operation, and other needs, can be
+  /// achieved by calling `range(of:options:range:locale:)`.
   ///
-  /// Equivalent to
+  /// Equivalent to:
   ///
-  ///     self.rangeOf(
-  ///       other, options: .CaseInsensitiveSearch,
-  ///       locale: Locale.current) != nil
-  public func localizedCaseInsensitiveContains(_ other: String) -> Bool {
+  ///     range(of: other, options: .caseInsensitiveSearch,
+  ///           locale: Locale.current) != nil
+  public func localizedCaseInsensitiveContains<
+    T : StringProtocol
+  >(_ other: T) -> Bool {
     let r = self.range(
       of: other, options: .caseInsensitive, locale: Locale.current
     ) != nil
     if #available(OSX 10.10, iOS 8.0, *) {
-      _sanityCheck(r == _ns.localizedCaseInsensitiveContains(other))
+      _sanityCheck(r ==
+        _ns.localizedCaseInsensitiveContains(other._ephemeralString))
     }
     return r
   }
 }
 
+// Deprecated slicing
+extension StringProtocol where Index == String.Index {
+  // - (NSString *)substringFromIndex:(NSUInteger)anIndex
+
+  /// Returns a new string containing the characters of the
+  /// `String` from the one at a given index to the end.
+  @available(swift, deprecated: 4.0,
+    message: "Please use String slicing subscript with a 'partial range from' operator.")
+  public func substring(from index: Index) -> String {
+    return _ns.substring(from: index.encodedOffset)
+  }
+
+  // - (NSString *)substringToIndex:(NSUInteger)anIndex
+
+  /// Returns a new string containing the characters of the
+  /// `String` up to, but not including, the one at a given index.
+  @available(swift, deprecated: 4.0,
+    message: "Please use String slicing subscript with a 'partial range upto' operator.")
+  public func substring(to index: Index) -> String {
+    return _ns.substring(to: index.encodedOffset)
+  }
+
+  // - (NSString *)substringWithRange:(NSRange)aRange
+
+  /// Returns a string object containing the characters of the
+  /// `String` that lie within a given range.
+  @available(swift, deprecated: 4.0,
+    message: "Please use String slicing subscript.")
+  public func substring(with aRange: Range<Index>) -> String {
+    return _ns.substring(with: _toRelativeNSRange(aRange))
+  }
+}
+
+extension StringProtocol {
+  // - (const char *)fileSystemRepresentation
+
+  /// Returns a file system-specific representation of the `String`.
+  @available(*, unavailable, message: "Use getFileSystemRepresentation on URL instead.")
+  public var fileSystemRepresentation: [CChar] {
+    fatalError("unavailable function can't be called")
+  }
+
+  // - (BOOL)
+  //     getFileSystemRepresentation:(char *)buffer
+  //     maxLength:(NSUInteger)maxLength
+
+  /// Interprets the `String` as a system-independent path and
+  /// fills a buffer with a C-string in a format and encoding suitable
+  /// for use with file-system calls.
+  /// - Note: will store a maximum of `min(buffer.count, maxLength)` bytes.
+  @available(*, unavailable, message: "Use getFileSystemRepresentation on URL instead.")
+  public func getFileSystemRepresentation(
+    _ buffer: inout [CChar], maxLength: Int) -> Bool {
+    fatalError("unavailable function can't be called")
+  }
+
+  //===--- Kept for consistency with API review results 5/20/2014 ---------===//
+  // We decided to keep pathWithComponents, so keeping this too
+  // @property NSString lastPathComponent;
+
+  /// Returns the last path component of the `String`.
+  @available(*, unavailable, message: "Use lastPathComponent on URL instead.")
+  public var lastPathComponent: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  //===--- Renamed by agreement during API review 5/20/2014 ---------------===//
+  // @property NSUInteger length;
+
+  /// Returns the number of Unicode characters in the `String`.
+  @available(*, unavailable,
+    message: "Take the count of a UTF-16 view instead, i.e. str.utf16.count")
+  public var utf16Count: Int {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSArray* pathComponents
+
+  /// Returns an array of NSString objects containing, in
+  /// order, each path component of the `String`.
+  @available(*, unavailable, message: "Use pathComponents on URL instead.")
+  public var pathComponents: [String] {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString* pathExtension;
+
+  /// Interprets the `String` as a path and returns the
+  /// `String`'s extension, if any.
+  @available(*, unavailable, message: "Use pathExtension on URL instead.")
+  public var pathExtension: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString *stringByAbbreviatingWithTildeInPath;
+
+  /// Returns a new string that replaces the current home
+  /// directory portion of the current path with a tilde (`~`)
+  /// character.
+  @available(*, unavailable, message: "Use abbreviatingWithTildeInPath on NSString instead.")
+  public var abbreviatingWithTildeInPath: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // - (NSString *)stringByAppendingPathComponent:(NSString *)aString
+
+  /// Returns a new string made by appending to the `String` a given string.
+  @available(*, unavailable, message: "Use appendingPathComponent on URL instead.")
+  public func appendingPathComponent(_ aString: String) -> String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // - (NSString *)stringByAppendingPathExtension:(NSString *)ext
+
+  /// Returns a new string made by appending to the `String` an
+  /// extension separator followed by a given extension.
+  @available(*, unavailable, message: "Use appendingPathExtension on URL instead.")
+  public func appendingPathExtension(_ ext: String) -> String? {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString* stringByDeletingLastPathComponent;
+
+  /// Returns a new string made by deleting the last path
+  /// component from the `String`, along with any final path
+  /// separator.
+  @available(*, unavailable, message: "Use deletingLastPathComponent on URL instead.")
+  public var deletingLastPathComponent: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString* stringByDeletingPathExtension;
+
+  /// Returns a new string made by deleting the extension (if
+  /// any, and only the last) from the `String`.
+  @available(*, unavailable, message: "Use deletingPathExtension on URL instead.")
+  public var deletingPathExtension: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString* stringByExpandingTildeInPath;
+
+  /// Returns a new string made by expanding the initial
+  /// component of the `String` to its full path value.
+  @available(*, unavailable, message: "Use expandingTildeInPath on NSString instead.")
+  public var expandingTildeInPath: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // - (NSString *)
+  //     stringByFoldingWithOptions:(StringCompareOptions)options
+  //     locale:(Locale *)locale
+
+  @available(*, unavailable, renamed: "folding(options:locale:)")
+  public func folding(
+    _ options: String.CompareOptions = [], locale: Locale?
+  ) -> String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // @property NSString* stringByResolvingSymlinksInPath;
+
+  /// Returns a new string made from the `String` by resolving
+  /// all symbolic links and standardizing path.
+  @available(*, unavailable, message: "Use resolvingSymlinksInPath on URL instead.")
+  public var resolvingSymlinksInPath: String {
+    fatalError("unavailable property")
+  }
+
+  // @property NSString* stringByStandardizingPath;
+
+  /// Returns a new string made by removing extraneous path
+  /// components from the `String`.
+  @available(*, unavailable, message: "Use standardizingPath on URL instead.")
+  public var standardizingPath: String {
+    fatalError("unavailable function can't be called")
+  }
+
+  // - (NSArray *)stringsByAppendingPaths:(NSArray *)paths
+
+  /// Returns an array of strings made by separately appending
+  /// to the `String` each string in a given array.
+  @available(*, unavailable, message: "Map over paths with appendingPathComponent instead.")
+  public func strings(byAppendingPaths paths: [String]) -> [String] {
+    fatalError("unavailable function can't be called")
+  }
+
+}
+
 // Pre-Swift-3 method names
 extension String {
-
   @available(*, unavailable, renamed: "localizedName(of:)")
   public static func localizedNameOfStringEncoding(
-    _ encoding: Encoding
+    _ encoding: String.Encoding
   ) -> String {
     fatalError("unavailable function can't be called")
   }
@@ -1526,8 +1872,20 @@
     fatalError("unavailable function can't be called")
   }
 
+  // + (NSString *)pathWithComponents:(NSArray *)components
+
+  /// Returns a string built from the strings in a given array
+  /// by concatenating them with a path separator between each pair.
+  @available(*, unavailable, message: "Use fileURL(withPathComponents:) on URL instead.")
+  public static func path(withComponents components: [String]) -> String {
+    fatalError("unavailable function can't be called")
+  }
+}
+
+extension StringProtocol {
+
   @available(*, unavailable, renamed: "canBeConverted(to:)")
-  public func canBeConvertedToEncoding(_ encoding: Encoding) -> Bool {
+  public func canBeConvertedToEncoding(_ encoding: String.Encoding) -> Bool {
     fatalError("unavailable function can't be called")
   }
 
@@ -1538,7 +1896,7 @@
 
   @available(*, unavailable, renamed: "commonPrefix(with:options:)")
   public func commonPrefixWith(
-    _ aString: String, options: CompareOptions) -> String {
+    _ aString: String, options: String.CompareOptions) -> String {
     fatalError("unavailable function can't be called")
   }
 
@@ -1565,22 +1923,36 @@
   }
 
   @available(*, unavailable, renamed: "cString(usingEncoding:)")
-  public func cStringUsingEncoding(_ encoding: Encoding) -> [CChar]? {
+  public func cStringUsingEncoding(_ encoding: String.Encoding) -> [CChar]? {
     fatalError("unavailable function can't be called")
   }
 
   @available(*, unavailable, renamed: "data(usingEncoding:allowLossyConversion:)")
   public func dataUsingEncoding(
-    _ encoding: Encoding,
+    _ encoding: String.Encoding,
     allowLossyConversion: Bool = false
   ) -> Data? {
     fatalError("unavailable function can't be called")
   }
 
+#if !DEPLOYMENT_RUNTIME_SWIFT
+  @available(*, unavailable, renamed: "enumerateLinguisticTags(in:scheme:options:orthography:_:)")
+  public func enumerateLinguisticTagsIn(
+    _ range: Range<Index>,
+    scheme tagScheme: String,
+    options opts: NSLinguisticTagger.Options,
+    orthography: NSOrthography?,
+    _ body:
+      (String, Range<Index>, Range<Index>, inout Bool) -> Void
+  ) {
+    fatalError("unavailable function can't be called")
+  }
+#endif
+
   @available(*, unavailable, renamed: "enumerateSubstrings(in:options:_:)")
   public func enumerateSubstringsIn(
     _ range: Range<Index>,
-    options opts: EnumerationOptions = [],
+    options opts: String.EnumerationOptions = [],
     _ body: (
       _ substring: String?, _ substringRange: Range<Index>,
       _ enclosingRange: Range<Index>, inout Bool
@@ -1594,8 +1966,8 @@
     _ buffer: inout [UInt8],
     maxLength maxBufferCount: Int,
     usedLength usedBufferCount: UnsafeMutablePointer<Int>,
-    encoding: Encoding,
-    options: EncodingConversionOptions = [],
+    encoding: String.Encoding,
+    options: String.EncodingConversionOptions = [],
     range: Range<Index>,
     remainingRange leftover: UnsafeMutablePointer<Range<Index>>
   ) -> Bool {
@@ -1623,7 +1995,7 @@
   }
 
   @available(*, unavailable, renamed: "lengthOfBytes(using:)")
-  public func lengthOfBytesUsingEncoding(_ encoding: Encoding) -> Int {
+  public func lengthOfBytesUsingEncoding(_ encoding: String.Encoding) -> Int {
     fatalError("unavailable function can't be called")
   }
 
@@ -1632,6 +2004,19 @@
     fatalError("unavailable function can't be called")
   }
 
+#if !DEPLOYMENT_RUNTIME_SWIFT
+  @available(*, unavailable, renamed: "linguisticTags(in:scheme:options:orthography:tokenRanges:)")
+  public func linguisticTagsIn(
+    _ range: Range<Index>,
+    scheme tagScheme: String,
+    options opts: NSLinguisticTagger.Options = [],
+    orthography: NSOrthography? = nil,
+    tokenRanges: UnsafeMutablePointer<[Range<Index>]>? = nil
+  ) -> [String] {
+    fatalError("unavailable function can't be called")
+  }
+#endif
+
   @available(*, unavailable, renamed: "lowercased(with:)")
   public func lowercaseStringWith(_ locale: Locale?) -> String {
     fatalError("unavailable function can't be called")
@@ -1639,7 +2024,7 @@
 
   @available(*, unavailable, renamed: "maximumLengthOfBytes(using:)")
   public
-  func maximumLengthOfBytesUsingEncoding(_ encoding: Encoding) -> Int {
+  func maximumLengthOfBytesUsingEncoding(_ encoding: String.Encoding) -> Int {
     fatalError("unavailable function can't be called")
   }
 
@@ -1651,7 +2036,7 @@
   @available(*, unavailable, renamed: "rangeOfCharacter(from:options:range:)")
   public func rangeOfCharacterFrom(
     _ aSet: CharacterSet,
-    options mask: CompareOptions = [],
+    options mask: String.CompareOptions = [],
     range aRange: Range<Index>? = nil
   ) -> Range<Index>? {
     fatalError("unavailable function can't be called")
@@ -1673,7 +2058,7 @@
   @available(*, unavailable, renamed: "range(of:options:range:locale:)")
   public func rangeOf(
     _ aString: String,
-    options mask: CompareOptions = [],
+    options mask: String.CompareOptions = [],
     range searchRange: Range<Index>? = nil,
     locale: Locale? = nil
   ) -> Range<Index>? {
@@ -1694,7 +2079,7 @@
 
   @available(*, unavailable, renamed: "addingPercentEscapes(using:)")
   public func addingPercentEscapesUsingEncoding(
-    _ encoding: Encoding
+    _ encoding: String.Encoding
   ) -> String? {
     fatalError("unavailable function can't be called")
   }
@@ -1712,7 +2097,7 @@
   ) -> String {
     fatalError("unavailable function can't be called")
   }
-  
+
   @available(*, unavailable, renamed: "replacingCharacters(in:with:)")
   public func replacingCharactersIn(
     _ range: Range<Index>, withString replacement: String
@@ -1724,7 +2109,7 @@
   public func replacingOccurrencesOf(
     _ target: String,
     withString replacement: String,
-    options: CompareOptions = [],
+    options: String.CompareOptions = [],
     range searchRange: Range<Index>? = nil
   ) -> String {
     fatalError("unavailable function can't be called")
@@ -1732,7 +2117,7 @@
 
   @available(*, unavailable, renamed: "replacingPercentEscapes(usingEncoding:)")
   public func replacingPercentEscapesUsingEncoding(
-    _ encoding: Encoding
+    _ encoding: String.Encoding
   ) -> String? {
     fatalError("unavailable function can't be called")
   }
@@ -1770,7 +2155,7 @@
   @available(*, unavailable, renamed: "write(toFile:atomically:encoding:)")
   public func writeToFile(
     _ path: String, atomically useAuxiliaryFile:Bool,
-    encoding enc: Encoding
+    encoding enc: String.Encoding
   ) throws {
     fatalError("unavailable function can't be called")
   }
@@ -1778,7 +2163,7 @@
   @available(*, unavailable, renamed: "write(to:atomically:encoding:)")
   public func writeToURL(
     _ url: URL, atomically useAuxiliaryFile: Bool,
-    encoding enc: Encoding
+    encoding enc: String.Encoding
   ) throws {
     fatalError("unavailable function can't be called")
   }
diff --git a/Foundation/NSSwiftRuntime.swift b/Foundation/NSSwiftRuntime.swift
index 2fae1df..33112a8 100644
--- a/Foundation/NSSwiftRuntime.swift
+++ b/Foundation/NSSwiftRuntime.swift
@@ -18,13 +18,73 @@
 @_exported import Glibc
 #endif
 
+@_exported import Dispatch
+
 #if os(Android) // shim required for bzero
 @_transparent func bzero(_ ptr: UnsafeMutableRawPointer, _ size: size_t) {
     memset(ptr, 0, size)
 }
 #endif
 
-public typealias ObjCBool = Bool
+#if !_runtime(_ObjC)
+/// The Objective-C BOOL type.
+///
+/// On 64-bit iOS, the Objective-C BOOL type is a typedef of C/C++
+/// bool. Elsewhere, it is "signed char". The Clang importer imports it as
+/// ObjCBool.
+@_fixed_layout
+public struct ObjCBool : ExpressibleByBooleanLiteral {
+    #if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+    // On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char".
+    var _value: Int8
+
+    init(_ value: Int8) {
+        self._value = value
+    }
+
+    public init(_ value: Bool) {
+        self._value = value ? 1 : 0
+    }
+
+    #else
+    // Everywhere else it is C/C++'s "Bool"
+    var _value: Bool
+
+    public init(_ value: Bool) {
+        self._value = value
+    }
+    #endif
+
+    /// The value of `self`, expressed as a `Bool`.
+    public var boolValue: Bool {
+        #if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+        return _value != 0
+        #else
+        return _value
+        #endif
+    }
+
+    /// Create an instance initialized to `value`.
+    @_transparent
+    public init(booleanLiteral value: Bool) {
+        self.init(value)
+    }
+}
+
+extension ObjCBool : CustomReflectable {
+    /// Returns a mirror that reflects `self`.
+    public var customMirror: Mirror {
+        return Mirror(reflecting: boolValue)
+    }
+}
+
+extension ObjCBool : CustomStringConvertible {
+    /// A textual representation of `self`.
+    public var description: String {
+        return self.boolValue.description
+    }
+}
+#endif
 
 internal class __NSCFType : NSObject {
     private var _cfinfo : Int32
@@ -80,11 +140,13 @@
     }
 }
 
+@_versioned
 @_cdecl("__CFSwiftGetBaseClass")
 internal func __CFSwiftGetBaseClass() -> UnsafeRawPointer {
     return unsafeBitCast(__NSCFType.self, to:UnsafeRawPointer.self)
 }
 
+@_versioned
 @_cdecl("__CFInitializeSwift")
 internal func __CFInitializeSwift() {
     
diff --git a/Foundation/NSTextCheckingResult.swift b/Foundation/NSTextCheckingResult.swift
index caed9a8..74dd8c0 100644
--- a/Foundation/NSTextCheckingResult.swift
+++ b/Foundation/NSTextCheckingResult.swift
@@ -87,7 +87,7 @@
 
 extension NSTextCheckingResult {
     
-    public func resultByAdjustingRangesWithOffset(_ offset: Int) -> NSTextCheckingResult {
+    public func adjustingRanges(offset: Int) -> NSTextCheckingResult {
         let count = self.numberOfRanges
         var newRanges = [NSRange]()
         for idx in 0..<count {
diff --git a/Foundation/NSURL.swift b/Foundation/NSURL.swift
index 9f06158..a02f49c 100644
--- a/Foundation/NSURL.swift
+++ b/Foundation/NSURL.swift
@@ -34,7 +34,7 @@
         if p.length == 0 {
             return result
         } else {
-            let characterView = p.characters
+            let characterView = p
             var curPos = characterView.startIndex
             let endPos = characterView.endIndex
             if characterView[curPos] == "/" {
@@ -309,7 +309,7 @@
 
         let thePath = _standardizedPath(path)
         
-        var isDir : Bool = false
+        var isDir: ObjCBool = false
         if thePath.hasSuffix("/") {
             isDir = true
         } else {
@@ -323,7 +323,7 @@
             let _ = FileManager.default.fileExists(atPath: absolutePath, isDirectory: &isDir)
         }
 
-        self.init(fileURLWithPath: thePath, isDirectory: isDir, relativeTo: baseURL)
+        self.init(fileURLWithPath: thePath, isDirectory: isDir.boolValue, relativeTo: baseURL)
     }
 
     public convenience init(fileURLWithPath path: String, isDirectory isDir: Bool) {
@@ -339,7 +339,7 @@
             thePath = path
         }
 
-        var isDir : Bool = false
+        var isDir: ObjCBool = false
         if thePath.hasSuffix("/") {
             isDir = true
         } else {
@@ -348,7 +348,7 @@
             }
         }
         super.init()
-        _CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPOSIXPathStyle, isDir, nil)
+        _CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPOSIXPathStyle, isDir.boolValue, nil)
     }
     
     public convenience init(fileURLWithFileSystemRepresentation path: UnsafePointer<Int8>, isDirectory isDir: Bool, relativeTo baseURL: URL?) {
@@ -405,7 +405,7 @@
         let buffer = malloc(bytesNeeded)!.bindMemory(to: UInt8.self, capacity: bytesNeeded)
         let bytesFilled = CFURLGetBytes(_cfObject, buffer, bytesNeeded)
         if bytesFilled == bytesNeeded {
-            return Data(bytesNoCopy: buffer, count: bytesNeeded, deallocator: .none)
+            return Data(bytesNoCopy: buffer, count: bytesNeeded, deallocator: .free)
         } else {
             fatalError()
         }
@@ -738,7 +738,7 @@
                 }
             }
             if stripTrailing && result.hasSuffix("/") {
-                result.remove(at: result.characters.index(before: result.characters.endIndex))
+                result.remove(at: result.index(before: result.endIndex))
             }
             return result
         }
@@ -757,7 +757,7 @@
             return fixedSelf
         }
         
-        return String(fixedSelf.characters.suffix(from: fixedSelf._startOfLastPathComponent))
+        return String(fixedSelf.suffix(from: fixedSelf._startOfLastPathComponent))
     }
     
     open var pathExtension: String? {
@@ -769,7 +769,7 @@
         }
         
         if let extensionPos = fixedSelf._startOfPathExtension {
-            return String(fixedSelf.characters.suffix(from: extensionPos))
+            return String(fixedSelf.suffix(from: extensionPos))
         } else {
             return ""
         }
@@ -779,8 +779,8 @@
         var result : URL? = appendingPathComponent(pathComponent, isDirectory: false)
         if !pathComponent.hasSuffix("/") && isFileURL {
             if let urlWithoutDirectory = result {
-                var isDir : Bool = false
-                if FileManager.default.fileExists(atPath: urlWithoutDirectory.path, isDirectory: &isDir) && isDir {
+                var isDir: ObjCBool = false
+                if FileManager.default.fileExists(atPath: urlWithoutDirectory.path, isDirectory: &isDir) && isDir.boolValue {
                     result = self.appendingPathComponent(pathComponent, isDirectory: true)
                 }
             }
@@ -859,14 +859,14 @@
         }
 
         // It might be a responsibility of NSURL(fileURLWithPath:). Check it.
-        var isExistingDirectory = false
+        var isExistingDirectory: ObjCBool = false
         let _ = FileManager.default.fileExists(atPath: resolvedPath, isDirectory: &isExistingDirectory)
 
         if excludeSystemDirs {
             resolvedPath = resolvedPath._tryToRemovePathPrefix("/private") ?? resolvedPath
         }
 
-        if isExistingDirectory && !resolvedPath.hasSuffix("/") {
+        if isExistingDirectory.boolValue && !resolvedPath.hasSuffix("/") {
             resolvedPath += "/"
         }
         
diff --git a/Foundation/Operation.swift b/Foundation/Operation.swift
index 1c5529f..ab09c1f 100644
--- a/Foundation/Operation.swift
+++ b/Foundation/Operation.swift
@@ -9,13 +9,8 @@
 
 #if DEPLOYMENT_ENABLE_LIBDISPATCH
 import Dispatch
-#if os(Linux) || os(Android)
+#endif
 import CoreFoundation
-private func pthread_main_np() -> Int32 {
-    return _CFIsMainThread() ? 1 : 0
-}
-#endif
-#endif
 
 open class Operation : NSObject {
     let lock = NSLock()
@@ -48,13 +43,15 @@
     }
     
     open func start() {
-        lock.lock()
-        _executing = true
-        lock.unlock()
-        main()
-        lock.lock()
-        _executing = false
-        lock.unlock()
+        if !isCancelled {
+            lock.lock()
+            _executing = true
+            lock.unlock()
+            main()
+            lock.lock()
+            _executing = false
+            lock.unlock()
+        }
         finish()
     }
     
@@ -84,9 +81,13 @@
     }
     
     open func cancel() {
+        // Note that calling cancel() is advisory. It is up to the main() function to
+        // call isCancelled at appropriate points in its execution flow and to do the
+        // actual canceling work. Eventually main() will invoke finish() and this is
+        // where we then leave the groups and unblock other operations that might
+        // depend on us.
         lock.lock()
         _cancelled = true
-        _leaveGroups()
         lock.unlock()
     }
     
@@ -570,7 +571,7 @@
     open class var current: OperationQueue? {
 #if DEPLOYMENT_ENABLE_LIBDISPATCH
         guard let specific = DispatchQueue.getSpecific(key: OperationQueue.OperationQueueKey) else {
-            if pthread_main_np() == 1 {
+            if _CFIsMainThread() {
                 return OperationQueue.main
             } else {
                 return nil
diff --git a/Foundation/ProcessInfo.swift b/Foundation/ProcessInfo.swift
index 10c32fe..baa9dab 100644
--- a/Foundation/ProcessInfo.swift
+++ b/Foundation/ProcessInfo.swift
@@ -92,7 +92,7 @@
             return OperatingSystemVersion(majorVersion: fallbackMajor, minorVersion: fallbackMinor, patchVersion: fallbackPatch)
         }
         
-        let versionComponents = productVersion._swiftObject.characters.split(separator: ".").map(String.init).flatMap({ Int($0) })
+        let versionComponents = productVersion._swiftObject.split(separator: ".").map(String.init).flatMap({ Int($0) })
         let majorVersion = versionComponents.dropFirst(0).first ?? fallbackMajor
         let minorVersion = versionComponents.dropFirst(1).first ?? fallbackMinor
         let patchVersion = versionComponents.dropFirst(2).first ?? fallbackPatch
diff --git a/Foundation/Stream.swift b/Foundation/Stream.swift
index 84dc566..d34949d 100644
--- a/Foundation/Stream.swift
+++ b/Foundation/Stream.swift
@@ -119,7 +119,7 @@
 
     // reads up to length bytes into the supplied buffer, which must be at least of size len. Returns the actual number of bytes read.
     open func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) -> Int {
-        return CFReadStreamRead(_stream, buffer, CFIndex(len._bridgeToObjectiveC()))
+        return CFReadStreamRead(_stream, buffer, len)
     }
     
     // returns in O(1) a pointer to the buffer in 'buffer' and by reference in 'len' how many bytes are available. This buffer is only valid until the next stream operation. Subclassers may return NO for this if it is not appropriate for the stream type. This may return NO if the buffer is not available.
diff --git a/Foundation/Thread.swift b/Foundation/Thread.swift
index 3990db0..402294d 100644
--- a/Foundation/Thread.swift
+++ b/Foundation/Thread.swift
@@ -13,29 +13,23 @@
 #elseif os(Linux) || CYGWIN
 import Glibc
 #endif
-
 import CoreFoundation
 
-// for some reason having this take a generic causes a crash...
-private func _compiler_crash_fix(_ key: _CFThreadSpecificKey, _ value: AnyObject?) {
-    _CThreadSpecificSet(key, value)
-}
-
 internal class NSThreadSpecific<T: NSObject> {
     private var key = _CFThreadSpecificKeyCreate()
-    
+
     internal func get(_ generator: () -> T) -> T {
         if let specific = _CFThreadSpecificGet(key) {
             return specific as! T
         } else {
             let value = generator()
-            _compiler_crash_fix(key, value)
+            _CFThreadSpecificSet(key, value)
             return value
         }
     }
-    
+
     internal func set(_ value: T) {
-        _compiler_crash_fix(key, value)
+        _CFThreadSpecificSet(key, value)
     }
 }
 
@@ -57,18 +51,33 @@
 }
 
 open class Thread : NSObject {
-    
+
     static internal var _currentThread = NSThreadSpecific<Thread>()
     open class var current: Thread {
         return Thread._currentThread.get() {
-            return Thread(thread: pthread_self())
+            if Thread.isMainThread {
+                return mainThread
+            } else {
+                return Thread(thread: pthread_self())
+            }
         }
     }
-    
-    open class var isMainThread: Bool { NSUnimplemented() }
-    
+
+    open class var isMainThread: Bool {
+        return _CFIsMainThread()
+    }
+
     // !!! NSThread's mainThread property is incorrectly exported as "main", which conflicts with its "main" method.
-    open class var mainThread: Thread { NSUnimplemented() }
+    private static let _mainThread: Thread = {
+        var thread = Thread(thread: _CFMainPThread)
+        thread._status = .executing
+        return thread
+    }()
+
+    open class var mainThread: Thread {
+        return _mainThread
+    }
+
 
     /// Alternative API for detached thread creation
     /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative to creation via selector
@@ -77,11 +86,11 @@
         let t = Thread(block: block)
         t.start()
     }
-    
+
     open class func isMultiThreaded() -> Bool {
         return true
     }
-    
+
     open class func sleep(until date: Date) {
         let start_ut = CFGetSystemUptime()
         let start_at = CFAbsoluteTimeGetCurrent()
@@ -127,9 +136,10 @@
     }
 
     open class func exit() {
+        Thread.current._status = .finished
         pthread_exit(nil)
     }
-    
+
     internal var _main: () -> Void = {}
 #if os(OSX) || os(iOS) || CYGWIN
     private var _thread: pthread_t? = nil
@@ -145,12 +155,12 @@
     internal var _cancelled = false
     /// - Note: this differs from the Darwin implementation in that the keys must be Strings
     open var threadDictionary = [String : Any]()
-    
+
     internal init(thread: pthread_t) {
         // Note: even on Darwin this is a non-optional pthread_t; this is only used for valid threads, which are never null pointers.
         _thread = thread
     }
-    
+
     public override init() {
         let _ = withUnsafeMutablePointer(to: &_attr) { attr in
             pthread_attr_init(attr)
@@ -158,7 +168,7 @@
             pthread_attr_setdetachstate(attr, Int32(PTHREAD_CREATE_DETACHED))
         }
     }
-    
+
     public convenience init(block: @escaping () -> Swift.Void) {
         self.init()
         _main = block
@@ -185,11 +195,11 @@
         }
 #endif
     }
-    
+
     open func main() {
         _main()
     }
-    
+
     open var name: String? {
         didSet {
             if _thread == Thread.current._thread {
@@ -227,25 +237,52 @@
     open var isFinished: Bool {
         return _status == .finished
     }
-    
+
     open var isCancelled: Bool {
         return _cancelled
     }
-    
+
     open var isMainThread: Bool {
-        NSUnimplemented()
+        return self === Thread.mainThread
     }
-    
+
     open func cancel() {
         _cancelled = true
     }
 
-    open class var callStackReturnAddresses: [NSNumber] {
-        NSUnimplemented()
+
+    private class func backtraceAddresses<T>(_ body: (UnsafeMutablePointer<UnsafeMutableRawPointer?>, Int) -> [T]) -> [T] {
+        // Same as swift/stdlib/public/runtime/Errors.cpp backtrace
+        let maxSupportedStackDepth = 128;
+        let addrs = UnsafeMutablePointer<UnsafeMutableRawPointer?>.allocate(capacity: maxSupportedStackDepth)
+        defer { addrs.deallocate(capacity: maxSupportedStackDepth) }
+        let count = backtrace(addrs, Int32(maxSupportedStackDepth))
+        let addressCount = max(0, min(Int(count), maxSupportedStackDepth))
+        return body(addrs, addressCount)
     }
-    
+
+    open class var callStackReturnAddresses: [NSNumber] {
+        return backtraceAddresses({ (addrs, count) in
+            UnsafeBufferPointer(start: addrs, count: count).map {
+                NSNumber(value: UInt(bitPattern: $0))
+            }
+        })
+    }
+
     open class var callStackSymbols: [String] {
-        NSUnimplemented()
+        return backtraceAddresses({ (addrs, count) in
+            var symbols: [String] = []
+            if let bs = backtrace_symbols(addrs, Int32(count)) {
+                symbols = UnsafeBufferPointer(start: bs, count: count).map {
+                    guard let symbol = $0 else {
+                        return "<null>"
+                    }
+                    return String(cString: symbol)
+                }
+                free(bs)
+            }
+            return symbols
+        })
     }
 }
 
diff --git a/Foundation/URLSession/URLSession.swift b/Foundation/URLSession/URLSession.swift
index 9dbb84c..8e707b3 100644
--- a/Foundation/URLSession/URLSession.swift
+++ b/Foundation/URLSession/URLSession.swift
@@ -137,11 +137,6 @@
 /// - SeeAlso: https://curl.haxx.se/libcurl/c/threadsafe.html
 /// - SeeAlso: URLSession+libcurl.swift
 ///
-/// The (publicly accessible) attributes of an `URLSessionTask` are made thread
-/// safe by using a concurrent libdispatch queue and only doing writes with a
-/// barrier while allowing concurrent reads. A single queue is shared for all
-/// tasks of a given session for this isolation. C.f. `taskAttributesIsolation`.
-///
 /// ## HTTP and RFC 2616
 ///
 /// Most of HTTP is defined in [RFC 2616](https://tools.ietf.org/html/rfc2616).
@@ -171,12 +166,21 @@
 import CoreFoundation
 import Dispatch
 
+extension URLSession {
+    public enum DelayedRequestDisposition {
+        case cancel
+        case continueLoading
+        case useNewRequest
+    }
+}
 
+fileprivate let globalVarSyncQ = DispatchQueue(label: "org.swift.Foundation.URLSession.GlobalVarSyncQ")
 fileprivate var sessionCounter = Int32(0)
 fileprivate func nextSessionIdentifier() -> Int32 {
-    //TODO: find an alternative for OSAtomicIncrement32Barrier() on Linux
-    sessionCounter += 1
-    return sessionCounter
+    return globalVarSyncQ.sync {
+        sessionCounter += 1
+        return sessionCounter
+    }
 }
 public let NSURLSessionTransferSizeUnknown: Int64 = -1
 
@@ -185,9 +189,6 @@
     fileprivate let multiHandle: _MultiHandle
     fileprivate var nextTaskIdentifier = 1
     internal let workQueue: DispatchQueue 
-    /// This queue is used to make public attributes on `URLSessionTask` instances thread safe.
-    /// - Note: It's a **concurrent** queue.
-    internal let taskAttributesIsolation: DispatchQueue 
     internal let taskRegistry = URLSession._TaskRegistry()
     fileprivate let identifier: Int32
     fileprivate var invalidated = false
@@ -213,7 +214,6 @@
         initializeLibcurl()
         identifier = nextSessionIdentifier()
         self.workQueue = DispatchQueue(label: "URLSession<\(identifier)>")
-        self.taskAttributesIsolation = DispatchQueue(label: "URLSession<\(identifier)>.taskAttributes", attributes: DispatchQueue.Attributes.concurrent)
         self.delegateQueue = OperationQueue()
         self.delegateQueue.maxConcurrentOperationCount = 1
         self.delegate = nil
@@ -236,7 +236,6 @@
         initializeLibcurl()
         identifier = nextSessionIdentifier()
         self.workQueue = DispatchQueue(label: "URLSession<\(identifier)>")
-        self.taskAttributesIsolation = DispatchQueue(label: "URLSession<\(identifier)>.taskAttributes", attributes: DispatchQueue.Attributes.concurrent)
         if let _queue = queue {
            self.delegateQueue = _queue
         } else {
@@ -397,9 +396,11 @@
 
 fileprivate extension URLSession {
     func createNextTaskIdentifier() -> Int {
-        let i = nextTaskIdentifier
-        nextTaskIdentifier += 1
-        return i
+        return workQueue.sync {
+            let i = nextTaskIdentifier
+            nextTaskIdentifier += 1
+            return i
+        }
     }
 }
 
diff --git a/Foundation/URLSession/URLSessionDelegate.swift b/Foundation/URLSession/URLSessionDelegate.swift
index ab9c077..3c65fb9 100644
--- a/Foundation/URLSession/URLSessionDelegate.swift
+++ b/Foundation/URLSession/URLSessionDelegate.swift
@@ -119,6 +119,8 @@
      * nil, which implies that no error occurred and this task is complete.
      */
      func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
+    
+     func urlSession(_ session: URLSession, task: URLSessionTask, willBeginDelayedRequest request: URLRequest, completionHandler: @escaping (URLSession.DelayedRequestDisposition, URLRequest?) -> Void)
 }
 
 extension URLSessionTaskDelegate {
@@ -137,6 +139,8 @@
     public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { }
     
     public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { }
+    
+    public func urlSession(_ session: URLSession, task: URLSessionTask, willBeginDelayedRequest request: URLRequest, completionHandler: @escaping (URLSession.DelayedRequestDisposition, URLRequest?) -> Void) { }
 }
 
 /*
@@ -194,6 +198,7 @@
      * message to receive the resource data.
      */
      func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void)
+    
 }
 
 extension URLSessionDataDelegate {
diff --git a/Foundation/URLSession/URLSessionTask.swift b/Foundation/URLSession/URLSessionTask.swift
index 1115ef5..98ded2c 100644
--- a/Foundation/URLSession/URLSessionTask.swift
+++ b/Foundation/URLSession/URLSessionTask.swift
@@ -21,22 +21,23 @@
 import CoreFoundation
 import Dispatch
 
-
 /// A cancelable object that refers to the lifetime
 /// of processing a given request.
 open class URLSessionTask : NSObject, NSCopying {
+    
+    public var countOfBytesClientExpectsToReceive: Int64 { NSUnimplemented() }
+    public var countOfBytesClientExpectsToSend: Int64 { NSUnimplemented() }
+    public var earliestBeginDate: Date? { NSUnimplemented() }
+    
     /// How many times the task has been suspended, 0 indicating a running task.
     internal var suspendCount = 1
     internal var session: URLSessionProtocol! //change to nil when task completes
     internal let body: _Body
-    fileprivate var _protocol: URLProtocol! = nil
+    fileprivate var _protocol: URLProtocol? = nil
+    private let syncQ = DispatchQueue(label: "org.swift.URLSessionTask.SyncQ")
     
     /// All operations must run on this queue.
     internal let workQueue: DispatchQueue 
-    /// Using dispatch semaphore to make public attributes thread safe.
-    /// A semaphore is a simpler option against the usage of concurrent queue
-    /// as the critical sections are very short.
-    fileprivate let semaphore = DispatchSemaphore(value: 1)    
     
     public override init() {
         // Darwin Foundation oddly allows calling this initializer, even though
@@ -62,7 +63,8 @@
     }
     internal init(session: URLSession, request: URLRequest, taskIdentifier: Int, body: _Body) {
         self.session = session
-        self.workQueue = session.workQueue
+        /* make sure we're actually having a serial queue as it's used for synchronization */
+        self.workQueue = DispatchQueue.init(label: "org.swift.URLSessionTask.WorkQueue", target: session.workQueue)
         self.taskIdentifier = taskIdentifier
         self.originalRequest = request
         self.body = body
@@ -108,31 +110,19 @@
     /// May differ from originalRequest due to http server redirection
     /*@NSCopying*/ open internal(set) var currentRequest: URLRequest? {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._currentRequest
+            return self.syncQ.sync { return self._currentRequest }
         }
         set {
-            semaphore.wait()
-            self._currentRequest = newValue
-            semaphore.signal()
+            self.syncQ.sync { self._currentRequest = newValue }
         }
     }
     fileprivate var _currentRequest: URLRequest? = nil
     /*@NSCopying*/ open internal(set) var response: URLResponse? {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._response
+            return self.syncQ.sync { return self._response }
         }
         set {
-            semaphore.wait()
-            self._response = newValue
-            semaphore.signal()
+            self.syncQ.sync { self._response = newValue }
         }
     }
     fileprivate var _response: URLResponse? = nil
@@ -145,16 +135,10 @@
     /// Number of body bytes already received
     open internal(set) var countOfBytesReceived: Int64 {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._countOfBytesReceived
+            return self.syncQ.sync { return self._countOfBytesReceived }
         }
         set {
-            semaphore.wait()
-            self._countOfBytesReceived = newValue
-            semaphore.signal()
+            self.syncQ.sync { self._countOfBytesReceived = newValue }
         }
     }
     fileprivate var _countOfBytesReceived: Int64 = 0
@@ -162,16 +146,10 @@
     /// Number of body bytes already sent */
     open internal(set) var countOfBytesSent: Int64 {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._countOfBytesSent
+            return self.syncQ.sync { return self._countOfBytesSent }
         }
         set {
-            semaphore.wait()
-            self._countOfBytesSent = newValue
-            semaphore.signal()
+            self.syncQ.sync { self._countOfBytesSent = newValue }
         }
     }
     
@@ -200,8 +178,8 @@
             self.workQueue.async {
                 let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled, userInfo: nil))
                 self.error = urlError
-                self._protocol.stopLoading()
-                self._protocol.client?.urlProtocol(self._protocol, didFailWithError: urlError)
+                self._protocol?.stopLoading()
+                self._protocol?.client?.urlProtocol(self._protocol!, didFailWithError: urlError)
             }
         }
     }
@@ -211,16 +189,10 @@
      */
     open var state: URLSessionTask.State {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._state
+            return self.syncQ.sync { self._state }
         }
         set {
-            semaphore.wait()
-            self._state = newValue
-            semaphore.signal()
+            self.syncQ.sync { self._state = newValue }
         }
     }
     fileprivate var _state: URLSessionTask.State = .suspended
@@ -263,7 +235,7 @@
             
             if self.suspendCount == 1 {
                 self.workQueue.async {
-                    self._protocol.stopLoading()
+                    self._protocol?.stopLoading()
                 }
             }
         }
@@ -278,7 +250,21 @@
             self.updateTaskState()
             if self.suspendCount == 0 {
                 self.workQueue.async {
-                    self._protocol.startLoading()
+                    if let _protocol = self._protocol {
+                        _protocol.startLoading()
+                    }
+                    else if self.error == nil {
+                        var userInfo: [String: Any] = [NSLocalizedDescriptionKey: "unsupported URL"]
+                        if let url = self.originalRequest?.url {
+                            userInfo[NSURLErrorFailingURLErrorKey] = url
+                            userInfo[NSURLErrorFailingURLStringErrorKey] = url.absoluteString
+                        }
+                        let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain,
+                                                                  code: NSURLErrorUnsupportedURL,
+                                                                  userInfo: userInfo))
+                        self.error = urlError
+                        _ProtocolClient().urlProtocol(task: self, didFailWithError: urlError)
+                    }
                 }
             }
         }
@@ -301,16 +287,10 @@
     /// URLSessionTask.highPriority, but use is not restricted to these.
     open var priority: Float {
         get {
-            semaphore.wait()
-            defer {
-                semaphore.signal()
-            }
-            return self._priority
+            return self.workQueue.sync { return self._priority }
         }
         set {
-            semaphore.wait()
-            self._priority = newValue
-            semaphore.signal()
+            self.workQueue.sync { self._priority = newValue }
         }
     }
     fileprivate var _priority: Float = URLSessionTask.defaultPriority
@@ -328,6 +308,12 @@
     }
 }
 
+extension URLSessionTask : ProgressReporting {
+    public var progress: Progress {
+        NSUnimplemented()
+    }
+}
+
 internal extension URLSessionTask {
     /// Updates the (public) state based on private / internal state.
     ///
@@ -555,7 +541,9 @@
             session.delegateQueue.addOperation {
                 delegate.urlSession(session, task: task, didCompleteWithError: nil)
                 task.state = .completed
-                session.taskRegistry.remove(task)
+                task.workQueue.async {
+                    session.taskRegistry.remove(task)
+                }
             }
         case .noDelegate:
             task.state = .completed
@@ -573,6 +561,7 @@
                 session.taskRegistry.remove(task)
             }
         }
+        task._protocol = nil
     }
 
     func urlProtocol(_ protocol: URLProtocol, didCancel challenge: URLAuthenticationChallenge) {
@@ -600,13 +589,19 @@
 
     func urlProtocol(_ protocol: URLProtocol, didFailWithError error: Error) {
         guard let task = `protocol`.task else { fatalError() }
+        urlProtocol(task: task, didFailWithError: error)
+    }
+
+    func urlProtocol(task: URLSessionTask, didFailWithError error: Error) {
         guard let session = task.session as? URLSession else { fatalError() }
         switch session.behaviour(for: task) {
         case .taskDelegate(let delegate):
             session.delegateQueue.addOperation {
                 delegate.urlSession(session, task: task, didCompleteWithError: error as Error)
                 task.state = .completed
-                session.taskRegistry.remove(task)
+                task.workQueue.async {
+                    session.taskRegistry.remove(task)
+                }
             }
         case .noDelegate:
             task.state = .completed
@@ -615,7 +610,9 @@
             session.delegateQueue.addOperation {
                 completion(nil, nil, error)
                 task.state = .completed
-                session.taskRegistry.remove(task)
+                task.workQueue.async {
+                    session.taskRegistry.remove(task)
+                }
             }
         case .downloadCompletionHandler(let completion):
             session.delegateQueue.addOperation {
@@ -624,6 +621,7 @@
                 session.taskRegistry.remove(task)
             }
         }
+        task._protocol = nil
     }
 
     func urlProtocol(_ protocol: URLProtocol, cachedResponseIsValid cachedResponse: CachedURLResponse) {
diff --git a/Foundation/URLSession/http/HTTPURLProtocol.swift b/Foundation/URLSession/http/HTTPURLProtocol.swift
index 307a64f..78aff84 100644
--- a/Foundation/URLSession/http/HTTPURLProtocol.swift
+++ b/Foundation/URLSession/http/HTTPURLProtocol.swift
@@ -13,13 +13,14 @@
 internal class _HTTPURLProtocol: URLProtocol {
 
     fileprivate var easyHandle: _EasyHandle!
-    fileprivate var tempFileURL: URL
+    fileprivate lazy var tempFileURL: URL = {
+        let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
+        _ = FileManager.default.createFile(atPath: fileName, contents: nil)
+        return URL(fileURLWithPath: fileName)
+    }()
 
     public required init(task: URLSessionTask, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
         self.internalState = _InternalState.initial
-        let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
-        _ = FileManager.default.createFile(atPath: fileName, contents: nil)
-        self.tempFileURL = URL(fileURLWithPath: fileName)
         super.init(request: task.originalRequest!, cachedResponse: cachedResponse, client: client)
         self.task = task
         self.easyHandle = _EasyHandle(delegate: self)
@@ -27,9 +28,6 @@
 
     public required init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
         self.internalState = _InternalState.initial
-        let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
-        _ = FileManager.default.createFile(atPath: fileName, contents: nil)
-        self.tempFileURL = URL(fileURLWithPath: fileName)
         super.init(request: request, cachedResponse: cachedResponse, client: client)
         self.easyHandle = _EasyHandle(delegate: self)
     }
diff --git a/Foundation/URLSession/http/MultiHandle.swift b/Foundation/URLSession/http/MultiHandle.swift
index bb2acaf..506c9a9 100644
--- a/Foundation/URLSession/http/MultiHandle.swift
+++ b/Foundation/URLSession/http/MultiHandle.swift
@@ -39,11 +39,7 @@
         let group = DispatchGroup()
         fileprivate var easyHandles: [_EasyHandle] = []
         fileprivate var timeoutSource: _TimeoutSource? = nil
-
-        //SR-4567: we need to synchronize the register/unregister commands to the epoll machinery in libdispatch
-        fileprivate let commandQueue: DispatchQueue = DispatchQueue(label: "Register-unregister synchronization")
-        fileprivate var cancelInProgress: DispatchSemaphore? = nil
-
+        
         init(configuration: URLSession._Configuration, workQueue: DispatchQueue) {
             queue = DispatchQueue(label: "MultiHandle.isolation", target: workQueue)
             setupCallbacks()
@@ -103,33 +99,25 @@
         // through libdispatch (DispatchSource) and store the source(s) inside
         // a `SocketSources` which we in turn store inside libcurl's multi handle
         // by means of curl_multi_assign() -- we retain the object fist.
-        commandQueue.async {
-            self.cancelInProgress?.wait()
-            self.cancelInProgress = nil
-
-            let action = _SocketRegisterAction(rawValue: CFURLSessionPoll(value: what))
-            var socketSources = _SocketSources.from(socketSourcePtr: socketSourcePtr)
-            if socketSources == nil && action.needsSource {
-                let s = _SocketSources()
-                let p = Unmanaged.passRetained(s).toOpaque()
-                CFURLSessionMultiHandleAssign(self.rawHandle, socket, UnsafeMutableRawPointer(p))
-                socketSources = s
-            } else if socketSources != nil && action == .unregister {
-                //the beginning of an unregister operation
-                self.cancelInProgress = DispatchSemaphore(value: 0)
-                // We need to release the stored pointer:
-                if let opaque = socketSourcePtr {
-                    Unmanaged<_SocketSources>.fromOpaque(opaque).release()
-                }
-                socketSources?.tearDown(self.cancelInProgress)
-                socketSources = nil
+        let action = _SocketRegisterAction(rawValue: CFURLSessionPoll(value: what))
+        var socketSources = _SocketSources.from(socketSourcePtr: socketSourcePtr)
+        if socketSources == nil && action.needsSource {
+            let s = _SocketSources()
+            let p = Unmanaged.passRetained(s).toOpaque()
+            CFURLSessionMultiHandleAssign(rawHandle, socket, UnsafeMutableRawPointer(p))
+            socketSources = s
+        } else if socketSources != nil && action == .unregister {
+            // We need to release the stored pointer:
+            if let opaque = socketSourcePtr {
+                Unmanaged<_SocketSources>.fromOpaque(opaque).release()
             }
-            if let ss = socketSources {
-                let handler = DispatchWorkItem { [weak self] in
-                    self?.performAction(for: socket)
-                }
-                ss.createSources(with: action, fileDescriptor: Int(socket), queue: self.queue, handler: handler)
+            socketSources = nil
+        }
+        if let ss = socketSources {
+            let handler = DispatchWorkItem { [weak self] in
+                self?.performAction(for: socket)
             }
+            ss.createSources(with: action, fileDescriptor: Int(socket), queue: queue, handler: handler)
         }
         return 0
     }
@@ -411,18 +399,12 @@
         s.resume()
     }
 
-    func tearDown(_ cancelInProgress: DispatchSemaphore?) {
-        let cancelHandler = DispatchWorkItem {
-            //the real end of an unregister operation!
-            cancelInProgress?.signal()
-        }
+    func tearDown() {
         if let s = readSource {
-            s.setCancelHandler(handler: cancelHandler)
             s.cancel()
         }
         readSource = nil
         if let s = writeSource {
-            s.setCancelHandler(handler: cancelHandler)
             s.cancel()
         }
         writeSource = nil
diff --git a/Foundation/Unit.swift b/Foundation/Unit.swift
index 92a9c6a..f43e5ff 100644
--- a/Foundation/Unit.swift
+++ b/Foundation/Unit.swift
@@ -79,6 +79,19 @@
     }
     
     public static var supportsSecureCoding: Bool { return true }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitConverterLinear else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return self.coefficient == other.coefficient
+            && self.constant == other.constant
+    }
 }
 
 private class UnitConverterReciprocal : UnitConverter, NSSecureCoding {
@@ -115,6 +128,18 @@
     }
     
     fileprivate static var supportsSecureCoding: Bool { return true }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitConverterReciprocal else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return self.reciprocal == other.reciprocal
+    }
 }
 
 /*
@@ -127,7 +152,7 @@
     open private(set) var symbol: String
     
     
-    public init(symbol: String) {
+    public required init(symbol: String) {
         self.symbol = symbol
     }
     
@@ -150,8 +175,20 @@
         }
         aCoder.encode(self.symbol._bridgeToObjectiveC(), forKey:"NS.symbol")
     }
-
+    
     public static var supportsSecureCoding: Bool { return true }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? Unit else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return self.symbol == other.symbol
+    }
 }
 
 open class Dimension : Unit {
@@ -159,8 +196,7 @@
     
     open private(set) var converter: UnitConverter
     
-    
-    public init(symbol: String, converter: UnitConverter) {
+    public required init(symbol: String, converter: UnitConverter) {
         self.converter = converter
         super.init(symbol: symbol)
     }
@@ -186,6 +222,11 @@
         super.init(symbol: symbol)
     }
     
+    public required init(symbol: String) {
+        let T = type(of: self)
+        fatalError("\(T) must be initialized with designated initializer \(T).init(symbol: String, converter: UnitConverter)")
+    }
+    
     open override func encode(with aCoder: NSCoder) {
         super.encode(with: aCoder)
         guard aCoder.allowsKeyedCoding else {
@@ -193,6 +234,18 @@
         }
         aCoder.encode(self.converter, forKey:"converter")
     }
+    
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? Dimension else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object) && self.converter == other.converter
+    }
 }
 
 open class UnitAcceleration : Dimension {
@@ -211,8 +264,8 @@
         static let gravity                  = 9.81
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var metersPerSecondSquared: UnitAcceleration {
@@ -231,9 +284,17 @@
         return UnitAcceleration.metersPerSecondSquared
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitAcceleration else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitAngle : Dimension {
@@ -260,11 +321,10 @@
         static let revolutions  = 360.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var degrees: UnitAngle {
         get {
             return UnitAngle(symbol: Symbol.degrees, coefficient: Coefficient.degrees)
@@ -305,9 +365,17 @@
         return UnitAngle.degrees
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitAngle else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitArea : Dimension {
@@ -350,11 +418,10 @@
         static let hectares             = 10000.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var squareMegameters: UnitArea {
         get {
             return UnitArea(symbol: Symbol.squareMegameters, coefficient: Coefficient.squareMegameters)
@@ -443,9 +510,17 @@
         return UnitArea.squareMeters
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitArea else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitConcentrationMass : Dimension {
@@ -466,11 +541,10 @@
         static let millimolesPerLiter       = 18.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var gramsPerLiter: UnitConcentrationMass {
         get {
             return UnitConcentrationMass(symbol: Symbol.gramsPerLiter, coefficient: Coefficient.gramsPerLiter)
@@ -491,9 +565,17 @@
         return UnitConcentrationMass.gramsPerLiter
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitConcentrationMass else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitDispersion : Dimension {
@@ -510,11 +592,10 @@
         static let partsPerMillion  = 1.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var partsPerMillion: UnitDispersion {
         get {
             return UnitDispersion(symbol: Symbol.partsPerMillion, coefficient: Coefficient.partsPerMillion)
@@ -525,9 +606,17 @@
         return UnitDispersion.partsPerMillion
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitDispersion else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitDuration : Dimension {
@@ -548,8 +637,8 @@
         static let hours    = 3600.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var seconds: UnitDuration {
@@ -574,9 +663,17 @@
         return UnitDuration.seconds
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitDuration else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitElectricCharge : Dimension {
@@ -602,11 +699,10 @@
         static let microampereHours = 0.0036
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var coulombs: UnitElectricCharge {
         get {
             return UnitElectricCharge(symbol: Symbol.coulombs, coefficient: Coefficient.coulombs)
@@ -647,9 +743,17 @@
         return UnitElectricCharge.coulombs
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitElectricCharge else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitElectricCurrent : Dimension {
@@ -657,6 +761,7 @@
     /*
      Base unit - amperes
      */
+    
     private struct Symbol {
         static let megaamperes  = "MA"
         static let kiloamperes  = "kA"
@@ -674,11 +779,10 @@
         
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var megaamperes: UnitElectricCurrent {
         get {
             return UnitElectricCurrent(symbol: Symbol.megaamperes, coefficient: Coefficient.megaamperes)
@@ -713,9 +817,17 @@
         return UnitElectricCurrent.amperes
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitElectricCurrent else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitElectricPotentialDifference : Dimension {
@@ -741,11 +853,10 @@
         
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var megavolts: UnitElectricPotentialDifference {
         get {
             return UnitElectricPotentialDifference(symbol: Symbol.megavolts, coefficient: Coefficient.megavolts)
@@ -780,9 +891,17 @@
         return UnitElectricPotentialDifference.volts
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitElectricPotentialDifference else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitElectricResistance : Dimension {
@@ -808,8 +927,8 @@
         
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var megaohms: UnitElectricResistance {
@@ -846,9 +965,17 @@
         return UnitElectricResistance.ohms
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitElectricResistance else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitEnergy : Dimension {
@@ -874,8 +1001,8 @@
         
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var kilojoules: UnitEnergy {
@@ -912,9 +1039,17 @@
         return UnitEnergy.joules
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitEnergy else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitFrequency : Dimension {
@@ -945,11 +1080,10 @@
         static let nanohertz    = 1e-9
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var terahertz: UnitFrequency {
         get {
             return UnitFrequency(symbol: Symbol.terahertz, coefficient: Coefficient.terahertz)
@@ -1002,9 +1136,17 @@
         return UnitFrequency.hertz
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitFrequency else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitFuelEfficiency : Dimension {
@@ -1025,11 +1167,10 @@
         static let milesPerGallon           = 235.215
     }
     
-    private init(symbol: String, reciprocal: Double) {
-        super.init(symbol: symbol, converter: UnitConverterReciprocal(reciprocal: reciprocal))
+    private convenience init(symbol: String, reciprocal: Double) {
+        self.init(symbol: symbol, converter: UnitConverterReciprocal(reciprocal: reciprocal))
     }
     
-    
     open class var litersPer100Kilometers: UnitFuelEfficiency {
         get {
             return UnitFuelEfficiency(symbol: Symbol.litersPer100Kilometers, reciprocal: Coefficient.litersPer100Kilometers)
@@ -1052,9 +1193,17 @@
         return UnitFuelEfficiency.litersPer100Kilometers
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitFuelEfficiency else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitLength : Dimension {
@@ -1113,8 +1262,8 @@
         static let parsecs              = 3.086e+16
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var megameters: UnitLength {
@@ -1253,9 +1402,17 @@
         return UnitLength.meters
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitLength else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitIlluminance : Dimension {
@@ -1272,8 +1429,8 @@
         static let lux   = 1.0
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var lux: UnitIlluminance {
@@ -1286,9 +1443,17 @@
         return UnitIlluminance.lux
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitIlluminance else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitMass : Dimension {
@@ -1335,8 +1500,8 @@
         static let slugs        = 14.5939
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var kilograms: UnitMass {
@@ -1439,9 +1604,17 @@
         return UnitMass.kilograms
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitMass else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitPower : Dimension {
@@ -1478,8 +1651,8 @@
         static let horsepower = 745.7
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
     open class var terawatts: UnitPower {
@@ -1552,9 +1725,17 @@
         return UnitPower.watts
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitPower else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitPressure : Dimension {
@@ -1589,11 +1770,10 @@
         static let poundsForcePerSquareInch = 6894.76
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var newtonsPerMetersSquared: UnitPressure {
         get {
             return UnitPressure(symbol: Symbol.newtonsPerMetersSquared, coefficient: Coefficient.newtonsPerMetersSquared)
@@ -1658,9 +1838,17 @@
         return UnitPressure.newtonsPerMetersSquared
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitPressure else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitSpeed : Dimension {
@@ -1683,11 +1871,10 @@
         static let knots                = 0.514444
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var metersPerSecond: UnitSpeed {
         get {
             return UnitSpeed(symbol: Symbol.metersPerSecond, coefficient: Coefficient.metersPerSecond)
@@ -1716,9 +1903,17 @@
         return UnitSpeed.metersPerSecond
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitSpeed else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitTemperature : Dimension {
@@ -1745,8 +1940,8 @@
         static let fahrenheit = 255.37222222222427
     }
     
-    private init(symbol: String, coefficient: Double, constant: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient, constant: constant))
+    private convenience init(symbol: String, coefficient: Double, constant: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient, constant: constant))
     }
     
     open class var kelvin: UnitTemperature {
@@ -1771,9 +1966,17 @@
         return UnitTemperature.kelvin
     }
     
-    
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitTemperature else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
 
 open class UnitVolume : Dimension {
@@ -1850,11 +2053,10 @@
         static let metricCups           = 0.25
     }
     
-    private init(symbol: String, coefficient: Double) {
-        super.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
+    private convenience init(symbol: String, coefficient: Double) {
+        self.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient))
     }
     
-    
     open class var megaliters: UnitVolume {
         get {
             return UnitVolume(symbol: Symbol.megaliters, coefficient: Coefficient.megaliters)
@@ -2045,6 +2247,15 @@
         return UnitVolume.liters
     }
     
-    public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
-    open override func encode(with aCoder: NSCoder) { super.encode(with: aCoder) }
+    open override func isEqual(_ object: Any?) -> Bool {
+        guard let other = object as? UnitVolume else {
+            return false
+        }
+        
+        if self === other {
+            return true
+        }
+        
+        return super.isEqual(object)
+    }
 }
diff --git a/Foundation/UserDefaults.swift b/Foundation/UserDefaults.swift
index 29d36fd..42cbd0d 100644
--- a/Foundation/UserDefaults.swift
+++ b/Foundation/UserDefaults.swift
@@ -45,37 +45,39 @@
         //Force the returned value to an NSObject
         switch CFGetTypeID(anObj) {
         case CFStringGetTypeID():
-            return (anObj as! CFString)._nsObject
+            return unsafeBitCast(anObj, to: NSString.self)
             
         case CFNumberGetTypeID():
-            return (anObj as! CFNumber)._nsObject
+            return unsafeBitCast(anObj, to: NSNumber.self)
             
         case CFURLGetTypeID():
-            return (anObj as! CFURL)._nsObject
+            return unsafeBitCast(anObj, to: NSURL.self)
             
         case CFArrayGetTypeID():
-            return (anObj as! CFArray)._nsObject
+            return unsafeBitCast(anObj, to: NSArray.self)
             
         case CFDictionaryGetTypeID():
-            return (anObj as! CFDictionary)._nsObject
-
+            return unsafeBitCast(anObj, to: NSDictionary.self)
+            
         case CFDataGetTypeID():
-            return (anObj as! CFData)._nsObject
+            return unsafeBitCast(anObj, to: NSData.self)
             
         default:
             return getFromRegistered()
         }
     }
+
     open func set(_ value: Any?, forKey defaultName: String) {
         guard let value = value else {
             CFPreferencesSetAppValue(defaultName._cfObject, nil, suite?._cfObject ?? kCFPreferencesCurrentApplication)
             return
         }
         
-        var cfType: CFTypeRef? = nil
+        let cfType: CFTypeRef
 		
-		//FIXME: is this needed? Am I overcomplicating things?
-        //Foundation types
+		// Convert the input value to the internal representation. All values are
+        // represented as CFTypeRef objects internally because we store the defaults
+        // in a CFPreferences type.
         if let bType = value as? NSNumber {
             cfType = bType._cfObject
         } else if let bType = value as? NSString {
@@ -84,11 +86,26 @@
             cfType = bType._cfObject
         } else if let bType = value as? NSDictionary {
             cfType = bType._cfObject
+        } else if let bType = value as? NSData {
+            cfType = bType._cfObject
+        } else if let bType = value as? NSURL {
+            set(URL(reference: bType), forKey: defaultName)
+            return
+        } else if let bType = value as? String {
+            cfType = bType._cfObject
         } else if let bType = value as? URL {
 			set(bType, forKey: defaultName)
 			return
+        } else if let bType = value as? Int {
+            var cfValue = Int64(bType)
+            cfType = CFNumberCreate(nil, kCFNumberSInt64Type, &cfValue)
+        } else if let bType = value as? Double {
+            var cfValue = bType
+            cfType = CFNumberCreate(nil, kCFNumberDoubleType, &cfValue)
         } else if let bType = value as? Data {
             cfType = bType._cfObject
+        } else {
+            fatalError("The type of 'value' passed to UserDefaults.set(forKey:) is not supported.")
         }
         
         CFPreferencesSetAppValue(defaultName._cfObject, cfType, suite?._cfObject ?? kCFPreferencesCurrentApplication)
@@ -140,10 +157,10 @@
     }
     open func data(forKey defaultName: String) -> Data? {
         guard let aVal = object(forKey: defaultName),
-              let bVal = aVal as? Data else {
+              let bVal = aVal as? NSData else {
             return nil
         }
-        return bVal
+        return Data(referencing: bVal)
     }
     open func stringArray(forKey defaultName: String) -> [String]? {
         guard let aVal = object(forKey: defaultName),
@@ -153,39 +170,61 @@
         return _SwiftValue.fetch(nonOptional: bVal) as? [String]
     }
     open func integer(forKey defaultName: String) -> Int {
-        guard let aVal = object(forKey: defaultName),
-              let bVal = aVal as? NSNumber else {
+        guard let aVal = object(forKey: defaultName) else {
             return 0
         }
-        return bVal.intValue
+        if let bVal = aVal as? NSNumber {
+            return bVal.intValue
+        }
+        if let bVal = aVal as? NSString {
+            return bVal.integerValue
+        }
+        return 0
     }
     open func float(forKey defaultName: String) -> Float {
-        guard let aVal = object(forKey: defaultName),
-              let bVal = aVal as? NSNumber else {
+        guard let aVal = object(forKey: defaultName) else {
             return 0
         }
-        return bVal.floatValue
+        if let bVal = aVal as? NSNumber {
+            return bVal.floatValue
+        }
+        if let bVal = aVal as? NSString {
+            return bVal.floatValue
+        }
+        return 0
     }
     open func double(forKey defaultName: String) -> Double {
-        guard let aVal = object(forKey: defaultName),
-              let bVal = aVal as? NSNumber else {
+        guard let aVal = object(forKey: defaultName) else {
             return 0
         }
-        return bVal.doubleValue
+        if let bVal = aVal as? NSNumber {
+            return bVal.doubleValue
+        }
+        if let bVal = aVal as? NSString {
+            return bVal.doubleValue
+        }
+        return 0
     }
     open func bool(forKey defaultName: String) -> Bool {
-        guard let aVal = object(forKey: defaultName),
-              let bVal = aVal as? NSNumber else {
+        guard let aVal = object(forKey: defaultName) else {
             return false
         }
-        return bVal.boolValue
+        if let bVal = aVal as? NSNumber {
+            return bVal.boolValue
+        }
+        if let bVal = aVal as? NSString {
+            return bVal.boolValue
+        }
+        return false
     }
     open func url(forKey defaultName: String) -> URL? {
         guard let aVal = object(forKey: defaultName) else {
             return nil
         }
         
-        if let bVal = aVal as? NSString {
+        if let bVal = aVal as? NSURL {
+            return URL(reference: bVal)
+        } else if let bVal = aVal as? NSString {
             let cVal = bVal.expandingTildeInPath
             
             return URL(fileURLWithPath: cVal)
@@ -227,10 +266,32 @@
     
     open func register(defaults registrationDictionary: [String : Any]) {
         for (key, value) in registrationDictionary {
-            registeredDefaults[key] = value
+            let nsValue: NSObject
+
+            // Converts a value to the internal representation. Internalized values are
+            // stored as NSObject derived objects in the registration dictionary.
+            if let val = value as? String {
+                nsValue = val._nsObject
+            } else if let val = value as? URL {
+                nsValue = val.path._nsObject
+            } else if let val = value as? Int {
+                nsValue = NSNumber(value: val)
+            } else if let val = value as? Double {
+                nsValue = NSNumber(value: val)
+            } else if let val = value as? Bool {
+                nsValue = NSNumber(value: val)
+            } else if let val = value as? Data {
+                nsValue = val._nsObject
+            } else if let val = value as? NSObject {
+                nsValue = val
+            } else {
+                fatalError("The type of 'value' passed to UserDefaults.register(defaults:) is not supported.")
+            }
+
+            registeredDefaults[key] = nsValue
         }
     }
-    
+
     open func addSuite(named suiteName: String) {
         CFPreferencesAddSuitePreferencesToApp(kCFPreferencesCurrentApplication, suiteName._cfObject)
     }
diff --git a/Foundation/XMLNode.swift b/Foundation/XMLNode.swift
index b1095d0..18c8719 100644
--- a/Foundation/XMLNode.swift
+++ b/Foundation/XMLNode.swift
@@ -421,7 +421,7 @@
         var entityChars: [Character] = []
         var inEntity = false
         var startIndex = 0
-        for (index, char) in string.characters.enumerated() {
+        for (index, char) in string.enumerated() {
             if char == "&" {
                 inEntity = true
                 startIndex = index
@@ -440,7 +440,7 @@
             }
         }
 
-        var result: [Character] = Array(string.characters)
+        var result: [Character] = Array(string)
         let doc = _CFXMLNodeGetDocument(_xmlNode)!
         for (range, entity) in entities {
             var entityPtr = _CFXMLGetDocEntity(doc, entity)
@@ -452,7 +452,7 @@
             }
             if let validEntity = entityPtr {
                 let replacement = _CFXMLCopyEntityContent(validEntity)?._swiftObject ?? ""
-                result.replaceSubrange(range, with: replacement.characters)
+                result.replaceSubrange(range, with: replacement)
             } else {
                 result.replaceSubrange(range, with: []) // This appears to be how Darwin Foundation does it
             }
diff --git a/Foundation/XMLParser.swift b/Foundation/XMLParser.swift
index c89f7eb..0b3c798 100644
--- a/Foundation/XMLParser.swift
+++ b/Foundation/XMLParser.swift
@@ -42,13 +42,14 @@
 }
 
 private func UTF8STRING(_ bytes: UnsafePointer<UInt8>?) -> String? {
-    guard let bytes = bytes else { return nil }
-    // strlen operates on the wrong type, char*. We can't rebind the memory to a different type without knowing its length,
-    // but since we know strlen is in libc, it's safe to directly bitcast the pointer without worrying about multiple accesses
-    // of different types visible to the compiler.
-    let len = strlen(unsafeBitCast(bytes, to: UnsafePointer<Int8>.self))
-    let str = String._fromCodeUnitSequence(UTF8.self, input: UnsafeBufferPointer(start: bytes, count: Int(len)))
-    return str
+    guard let bytes = bytes else {
+        return nil
+    }
+    if let (str, _) = String.decodeCString(bytes, as: UTF8.self,
+                                           repairingInvalidCodeUnits: false) {
+        return str
+    }
+    return nil
 }
 
 internal func _NSXMLParserCurrentParser() -> _CFXMLInterface? {
diff --git a/TestFoundation/HTTPServer.swift b/TestFoundation/HTTPServer.swift
index b129f74..ec2055f 100644
--- a/TestFoundation/HTTPServer.swift
+++ b/TestFoundation/HTTPServer.swift
@@ -16,16 +16,22 @@
 
 #if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
     import Foundation
-    import Glibc
     import XCTest
 #else
-    import CoreFoundation
     import SwiftFoundation
-    import Darwin
     import SwiftXCTest
 #endif
 
+#if os(OSX) || os(iOS)
+    import Darwin
+#elseif os(Linux)
+    import Glibc
+#endif
+
+
 public let globalDispatchQueue = DispatchQueue.global()
+public let dispatchQueueMake: (String) -> DispatchQueue = { DispatchQueue.init(label: $0) }
+public let dispatchGroupMake: () -> DispatchGroup = DispatchGroup.init
 
 struct _HTTPUtils {
     static let CRLF = "\r\n"
@@ -35,6 +41,12 @@
     static let EMPTY = ""
 }
 
+extension UInt16 {
+    public init(networkByteOrder input: UInt16) {
+        self.init(bigEndian: input)
+    }
+}
+
 class _TCPSocket {
   
     private var listenSocket: Int32!
@@ -55,12 +67,15 @@
         return r
     }
 
-    init(port: UInt16) throws {
+    public private(set) var port: UInt16
+
+    init(port: UInt16?) throws {
         #if os(Linux)
             let SOCKSTREAM = Int32(SOCK_STREAM.rawValue)
         #else
             let SOCKSTREAM = SOCK_STREAM
         #endif
+        self.port = port ?? 0
         listenSocket = try attempt("socket", valid: isNotNegative, socket(AF_INET, SOCKSTREAM, Int32(IPPROTO_TCP)))
         var on: Int = 1
         _ = try attempt("setsockopt", valid: isZero, setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &on, socklen_t(MemoryLayout<Int>.size)))
@@ -70,16 +85,27 @@
             let addr = UnsafePointer<sockaddr>($0)
             _ = try attempt("bind", valid: isZero, bind(listenSocket, addr, socklen_t(MemoryLayout<sockaddr>.size)))
         })
+
+        var actualSA = sockaddr_in()
+        withUnsafeMutablePointer(to: &actualSA) { ptr in
+            ptr.withMemoryRebound(to: sockaddr.self, capacity: 1) { (ptr: UnsafeMutablePointer<sockaddr>) in
+                var len = socklen_t(MemoryLayout<sockaddr>.size)
+                getsockname(listenSocket, ptr, &len)
+            }
+        }
+
+        self.port = UInt16(networkByteOrder: actualSA.sin_port)
     }
 
-    private func createSockaddr(_ port: UInt16) -> sockaddr_in {
+    private func createSockaddr(_ port: UInt16?) -> sockaddr_in {
         // Listen on the loopback address so that OSX doesnt pop up a dialog
         // asking to accept incoming connections if the firewall is enabled.
         let addr = UInt32(INADDR_LOOPBACK).bigEndian
+        let netPort = UInt16(bigEndian: port ?? 0)
         #if os(Linux)
-            return sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: htons(port), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
+            return sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: netPort, sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
         #else
-            return sockaddr_in(sin_len: 0, sin_family: sa_family_t(AF_INET), sin_port: CFSwapInt16HostToBig(port), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
+            return sockaddr_in(sin_len: 0, sin_family: sa_family_t(AF_INET), sin_port: netPort, sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
         #endif
     }
 
@@ -100,7 +126,7 @@
     }
     
     func split(_ str: String, _ count: Int) -> [String] {
-        return stride(from: 0, to: str.characters.count, by: count).map { i -> String in
+        return stride(from: 0, to: str.count, by: count).map { i -> String in
             let startIndex = str.index(str.startIndex, offsetBy: i)
             let endIndex   = str.index(startIndex, offsetBy: count, limitedBy: str.endIndex) ?? str.endIndex
             return String(str[startIndex..<endIndex])
@@ -133,20 +159,27 @@
     }
 
     func shutdown() {
-        close(connectionSocket)
+        if let connectionSocket = self.connectionSocket {
+            close(connectionSocket)
+        }
         close(listenSocket)
     }
 }
 
 class _HTTPServer {
 
-    let socket: _TCPSocket 
+    let socket: _TCPSocket
+    var port: UInt16 {
+        get {
+            return self.socket.port
+        }
+    }
     
-    init(port: UInt16) throws {
+    init(port: UInt16?) throws {
         socket = try _TCPSocket(port: port)
     }
 
-    public class func create(port: UInt16) throws -> _HTTPServer {
+    public class func create(port: UInt16?) throws -> _HTTPServer {
         return try _HTTPServer(port: port)
     }
 
@@ -159,7 +192,7 @@
     }
    
     public func request() throws -> _HTTPRequest {
-       return _HTTPRequest(request: try socket.readData()) 
+       return try _HTTPRequest(request: socket.readData())
     }
 
     public func respond(with response: _HTTPResponse, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
@@ -307,8 +340,13 @@
     let startDelay: TimeInterval?
     let sendDelay: TimeInterval?
     let bodyChunks: Int?
+    var port: UInt16 {
+        get {
+            return self.httpServer.port
+        }
+    }
     
-    public init (port: UInt16, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
+    public init (port: UInt16?, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
         httpServer = try _HTTPServer.create(port: port)
         self.startDelay = startDelay
         self.sendDelay = sendDelay
@@ -346,7 +384,7 @@
         }
 
         if uri == "/country.txt" {
-            let text = capitals[String(uri.characters.dropFirst())]!
+            let text = capitals[String(uri.dropFirst())]!
             return _HTTPResponse(response: .OK, headers: "Content-Length: \(text.data(using: .utf8)!.count)", body: text)
         }
 
@@ -356,7 +394,7 @@
         }
 
 	if uri == "/UnitedStates" {
-            let value = capitals[String(uri.characters.dropFirst())]!
+            let value = capitals[String(uri.dropFirst())]!
             let text = request.getCommaSeparatedHeaders()
             let host = request.headers[1].components(separatedBy: " ")[1]
             let ip = host.components(separatedBy: ":")[0]
@@ -366,7 +404,7 @@
             let httpResponse = _HTTPResponse(response: .REDIRECT, headers: "Location: http://\(newHost + "/" + value)", body: text)
             return httpResponse 
         }
-        return _HTTPResponse(response: .OK, body: capitals[String(uri.characters.dropFirst())]!) 
+        return _HTTPResponse(response: .OK, body: capitals[String(uri.dropFirst())]!)
     }
 
     func stop() {
@@ -404,23 +442,28 @@
 }
 
 class LoopbackServerTest : XCTestCase {
-    static var serverPort: Int = -1
+    private static let staticSyncQ = DispatchQueue(label: "org.swift.TestFoundation.HTTPServer.StaticSyncQ")
+
+    private static var _serverPort: Int = -1
+    static var serverPort: Int {
+        get {
+            return staticSyncQ.sync { _serverPort }
+        }
+        set {
+            staticSyncQ.sync { _serverPort = newValue }
+        }
+    }
 
     override class func setUp() {
         super.setUp()
         func runServer(with condition: ServerSemaphore, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
-            let start = 21961
-            for port in start...(start+100) { //we must find at least one port to bind
-                do {
-                    serverPort = port
-                    let test = try TestURLSessionServer(port: UInt16(port), startDelay: startDelay, sendDelay: sendDelay, bodyChunks: bodyChunks)
-                    try test.start(started: condition)
-                    try test.readAndRespond()
-                    test.stop()
-                } catch let e as ServerError {
-                    if e.operation == "bind" { continue }
-                    throw e
-                }
+            while true {
+                let test = try TestURLSessionServer(port: nil, startDelay: startDelay, sendDelay: sendDelay, bodyChunks: bodyChunks)
+                serverPort = Int(test.port)
+                try test.start(started: condition)
+                try test.readAndRespond()
+                serverPort = -2
+                test.stop()
             }
         }
 
diff --git a/TestFoundation/TestAffineTransform.swift b/TestFoundation/TestAffineTransform.swift
index f1d1a51..9a897ad 100644
--- a/TestFoundation/TestAffineTransform.swift
+++ b/TestFoundation/TestAffineTransform.swift
@@ -38,6 +38,9 @@
             ("test_AppendTransform", test_AppendTransform),
             ("test_PrependTransform", test_PrependTransform),
             ("test_TransformComposition", test_TransformComposition),
+            ("test_hashing_identity", test_hashing_identity),
+            ("test_hashing_values", test_hashing_values),
+            ("test_rotation_compose", test_rotation_compose),
             ("test_Equal", test_Equal),
             ("test_NSCoding", test_NSCoding),
         ]
@@ -345,6 +348,16 @@
             XCTAssertEqual(ref.hashValue, val.hashValue)
         }
     }
+
+    func test_rotation_compose() {
+        var t = AffineTransform.identity
+        t.translate(x: 1.0, y: 1.0)
+        t.rotate(byDegrees: 90)
+        t.translate(x: -1.0, y: -1.0)
+        let result = t.transform(NSPoint(x: 1.0, y: 2.0))
+        XCTAssertEqual(0.0, Double(result.x), accuracy: accuracyThreshold)
+        XCTAssertEqual(1.0, Double(result.y), accuracy: accuracyThreshold)
+    }
     
     func test_Equal() {
         let transform = NSAffineTransform()
diff --git a/TestFoundation/TestByteCountFormatter.swift b/TestFoundation/TestByteCountFormatter.swift
index 8046a0f..c077266 100644
--- a/TestFoundation/TestByteCountFormatter.swift
+++ b/TestFoundation/TestByteCountFormatter.swift
@@ -49,7 +49,7 @@
     
     func test_DefaultValues() {
         let formatter = ByteCountFormatter()
-        XCTAssertEqual(formatter.allowedUnits, ByteCountFormatter.Units.useDefault)
+        XCTAssertEqual(formatter.allowedUnits, [])
         XCTAssertEqual(formatter.countStyle, ByteCountFormatter.CountStyle.file)
         XCTAssertEqual(formatter.allowsNonnumericFormatting, true)
         XCTAssertEqual(formatter.includesUnit, true)
@@ -68,7 +68,7 @@
         formatter.allowedUnits = .useGB
         XCTAssertEqual(formatter.string(fromByteCount: 0), "Zero KB")
         
-        formatter.allowedUnits = .useDefault
+        formatter.allowedUnits = []
         formatter.allowsNonnumericFormatting = false
         XCTAssertEqual(formatter.string(fromByteCount: 0), "0 bytes")
         
@@ -91,7 +91,7 @@
         formatter.allowedUnits = .useGB
         XCTAssertEqual(formatter.string(fromByteCount: 1), "0 GB")
         
-        formatter.allowedUnits = .useDefault
+        formatter.allowedUnits = []
         formatter.isAdaptive = false
         XCTAssertEqual(formatter.string(fromByteCount: 1), "1 byte")
         
@@ -365,7 +365,7 @@
         XCTAssertEqual(formatter.string(fromByteCount: 11999), "12.0 KB")
         XCTAssertEqual(formatter.string(fromByteCount: 900000), "900 KB")
         XCTAssertEqual(formatter.string(fromByteCount: 12345678), "12.3 MB")
-        XCTAssertEqual(formatter.string(fromByteCount: 123456789), "123.5 MB")
+        XCTAssertEqual(formatter.string(fromByteCount: 123456789), "123 MB")
         XCTAssertEqual(formatter.string(fromByteCount: 1234567898), "1.23 GB")
         XCTAssertEqual(formatter.string(fromByteCount: 12345678987), "12.3 GB")
     }
diff --git a/TestFoundation/TestCalendar.swift b/TestFoundation/TestCalendar.swift
index 07198f2..0e90ace 100644
--- a/TestFoundation/TestCalendar.swift
+++ b/TestFoundation/TestCalendar.swift
@@ -14,7 +14,6 @@
 import SwiftFoundation
 import SwiftXCTest
 #endif
-import CoreFoundation
 
 class TestCalendar: XCTestCase {
     
diff --git a/TestFoundation/TestCodable.swift b/TestFoundation/TestCodable.swift
index c43becf..f1fb7d6 100644
--- a/TestFoundation/TestCodable.swift
+++ b/TestFoundation/TestCodable.swift
@@ -399,6 +399,13 @@
         let components = calendar.dateComponents(dateComponents, from: Date(timeIntervalSince1970: 1501283776))
         expectRoundTripEqualityThroughJSON(for: components)
     }
+
+    // MARK: - Measurement
+    func test_Measurement_JSON() {
+        expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: UnitAcceleration.metersPerSecondSquared))
+        expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: UnitMass.kilograms))
+        expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: UnitLength.miles))
+    }
 }
 
 extension TestCodable {
@@ -420,6 +427,7 @@
             ("test_TimeZone_JSON", test_TimeZone_JSON),
             ("test_Calendar_JSON", test_Calendar_JSON),
             ("test_DateComponents_JSON", test_DateComponents_JSON),
+            ("test_Measurement_JSON", test_Measurement_JSON),
         ]
     }
 }
diff --git a/TestFoundation/TestDateFormatter.swift b/TestFoundation/TestDateFormatter.swift
index afcebaf..f21ecb1 100644
--- a/TestFoundation/TestDateFormatter.swift
+++ b/TestFoundation/TestDateFormatter.swift
@@ -29,6 +29,7 @@
             ("test_dateStyleFull",     test_dateStyleFull),
             ("test_customDateFormat", test_customDateFormat),
             ("test_setLocalizedDateFormatFromTemplate", test_setLocalizedDateFormatFromTemplate),
+            ("test_dateFormatString", test_dateFormatString),
         ]
     }
     
@@ -295,4 +296,45 @@
         XCTAssertEqual(f.dateFormat, dateFormat)
     }
 
+    func test_dateFormatString() {
+        let f = DateFormatter()
+        f.timeZone = TimeZone(abbreviation: DEFAULT_TIMEZONE)
+        
+        //.full cases have been commented out as they're not working correctly on Linux
+        let formats: [String: (DateFormatter.Style, DateFormatter.Style)] = [
+            "": (.none, .none),
+            "h:mm a": (.none, .short),
+            "h:mm:ss a": (.none, .medium),
+            "h:mm:ss a z": (.none, .long),
+//            "h:mm:ss a zzzz": (.none, .full),
+            "M/d/yy": (.short, .none),
+            "M/d/yy, h:mm a": (.short, .short),
+            "M/d/yy, h:mm:ss a": (.short, .medium),
+            "M/d/yy, h:mm:ss a z": (.short, .long),
+//            "M/d/yy, h:mm:ss a zzzz": (.short, .full),
+            "MMM d, y": (.medium, .none),
+            //These tests currently fail, there seems to be a difference in behavior in the CoreFoundation methods called to construct the format strings.
+//            "MMM d, y 'at' h:mm a": (.medium, .short),
+//            "MMM d, y 'at' h:mm:ss a": (.medium, .medium),
+//            "MMM d, y 'at' h:mm:ss a z": (.medium, .long),
+//            "MMM d, y 'at' h:mm:ss a zzzz": (.medium, .full),
+            "MMMM d, y": (.long, .none),
+            "MMMM d, y 'at' h:mm a": (.long, .short),
+            "MMMM d, y 'at' h:mm:ss a": (.long, .medium),
+            "MMMM d, y 'at' h:mm:ss a z": (.long, .long),
+//            "MMMM d, y 'at' h:mm:ss a zzzz": (.long, .full),
+//            "EEEE, MMMM d, y": (.full, .none),
+//            "EEEE, MMMM d, y 'at' h:mm a": (.full, .short),
+//            "EEEE, MMMM d, y 'at' h:mm:ss a": (.full, .medium),
+//            "EEEE, MMMM d, y 'at' h:mm:ss a z": (.full, .long),
+//            "EEEE, MMMM d, y 'at' h:mm:ss a zzzz": (.full, .full),
+        ]
+        
+        for (dateFormat, styles) in formats {
+            f.dateStyle = styles.0
+            f.timeStyle = styles.1
+            
+            XCTAssertEqual(f.dateFormat, dateFormat)
+        }
+    }
 }
diff --git a/TestFoundation/TestDecimal.swift b/TestFoundation/TestDecimal.swift
index 3abe3b9..f34d9f7 100644
--- a/TestFoundation/TestDecimal.swift
+++ b/TestFoundation/TestDecimal.swift
@@ -260,7 +260,7 @@
                     var failed: Bool = false
                     var count = 0
                     let SIG_FIG = 14
-                    for (a, b) in zip(answerDescription.characters, approximationDescription.characters) {
+                    for (a, b) in zip(answerDescription, approximationDescription) {
                         if a != b {
                             failed = true
                             break
@@ -289,6 +289,9 @@
         XCTAssertEqual(.minus, d.sign)
         d.negate()
         XCTAssertEqual(.plus, d.sign)
+        var e = Decimal(0)
+        e.negate()
+        XCTAssertEqual(e, 0)
         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)))
@@ -404,7 +407,7 @@
         XCTAssertNotEqual(.noError, NSDecimalMultiplyByPowerOf10(&result, &NaN, 5, .plain))
         XCTAssertTrue(NSDecimalIsNotANumber(&result), "NaN e5")
 
-        XCTAssertFalse(Double(NSDecimalNumber(decimal:Decimal(0))).isNaN)
+        XCTAssertFalse(Double(truncating: NSDecimalNumber(decimal: Decimal(0))).isNaN)
     }
 
     func test_NegativeAndZeroMultiplication() {
diff --git a/TestFoundation/TestFileManager.swift b/TestFoundation/TestFileManager.swift
index a9cb932..90d1597 100644
--- a/TestFoundation/TestFileManager.swift
+++ b/TestFoundation/TestFileManager.swift
@@ -31,6 +31,7 @@
             ("test_subpathsOfDirectoryAtPath", test_subpathsOfDirectoryAtPath),
             ("test_copyItemAtPathToPath", test_copyItemAtPathToPath),
             ("test_homedirectoryForUser", test_homedirectoryForUser),
+            ("test_temporaryDirectoryForUser", test_temporaryDirectoryForUser),
         ]
     }
     
@@ -53,10 +54,10 @@
         // Ensure attempting to create the directory again fails gracefully.
         XCTAssertNil(try? fm.createDirectory(atPath: path, withIntermediateDirectories:false, attributes:nil))
 
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
         XCTAssertTrue(exists)
-        XCTAssertTrue(isDir)
+        XCTAssertTrue(isDir.boolValue)
 
         do {
             try fm.removeItem(atPath: path)
@@ -74,10 +75,10 @@
         
         XCTAssertTrue(fm.createFile(atPath: path, contents: Data(), attributes: nil))
         
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
         XCTAssertTrue(exists)
-        XCTAssertFalse(isDir)
+        XCTAssertFalse(isDir.boolValue)
         
         do {
             try fm.removeItem(atPath: path)
@@ -467,9 +468,9 @@
         }
         
         func directoryExists(atPath path: String) -> Bool {
-            var isDir = false
+            var isDir: ObjCBool = false
             let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
-            return exists && isDir
+            return exists && isDir.boolValue
         }
         
         func createDirectory(atPath path: String) {
@@ -525,4 +526,25 @@
         XCTAssertNil(filemanger.homeDirectory(forUser: ""))
         XCTAssertNotNil(filemanger.homeDirectoryForCurrentUser)
     }
+    
+    func test_temporaryDirectoryForUser() {
+        let filemanger = FileManager.default
+        let tmpDir = filemanger.temporaryDirectory
+        XCTAssertNotNil(tmpDir)
+        let tmpFileUrl = tmpDir.appendingPathComponent("test.bin")
+        let tmpFilePath = tmpFileUrl.path
+        
+        do {
+            if filemanger.fileExists(atPath: tmpFilePath) {
+                try filemanger.removeItem(at: tmpFileUrl)
+            }
+            
+            try "hello world".write(to: tmpFileUrl, atomically: false, encoding: .utf8)
+            XCTAssert(filemanger.fileExists(atPath: tmpFilePath))
+
+            try filemanger.removeItem(at: tmpFileUrl)
+        } catch {
+            XCTFail("Unable to write a file to the temporary directory: \(tmpDir), err: \(error)")
+        }
+    }
 }
diff --git a/TestFoundation/TestHTTPCookieStorage.swift b/TestFoundation/TestHTTPCookieStorage.swift
index bea3391..f65a01e 100644
--- a/TestFoundation/TestHTTPCookieStorage.swift
+++ b/TestFoundation/TestHTTPCookieStorage.swift
@@ -14,6 +14,7 @@
     import SwiftFoundation
     import SwiftXCTest
 #endif
+import Dispatch
 
 class TestHTTPCookieStorage: XCTestCase {
 
@@ -24,6 +25,7 @@
 
     static var allTests: [(String, (TestHTTPCookieStorage) -> () throws -> Void)] {
         return [
+            ("test_sharedCookieStorageAccessedFromMultipleThreads", test_sharedCookieStorageAccessedFromMultipleThreads),
             ("test_BasicStorageAndRetrieval", test_BasicStorageAndRetrieval),
             ("test_deleteCookie", test_deleteCookie),
             ("test_removeCookies", test_removeCookies),
@@ -34,6 +36,27 @@
         ]
     }
 
+    func test_sharedCookieStorageAccessedFromMultipleThreads() {
+        let q = DispatchQueue.global()
+        let syncQ = DispatchQueue(label: "TestHTTPCookieStorage.syncQ")
+        var allCookieStorages: [HTTPCookieStorage] = []
+        let g = DispatchGroup()
+        for _ in 0..<64 {
+            g.enter()
+            q.async {
+                let mySharedCookieStore = HTTPCookieStorage.shared
+                syncQ.async {
+                    allCookieStorages.append(mySharedCookieStore)
+                    g.leave()
+                }
+            }
+        }
+        g.wait()
+        let cookieStorages = syncQ.sync { allCookieStorages }
+        let mySharedCookieStore = HTTPCookieStorage.shared
+        XCTAssertTrue(cookieStorages.reduce(true, { $0 && $1 === mySharedCookieStore }), "\(cookieStorages)")
+    }
+
     func test_BasicStorageAndRetrieval() {
         basicStorageAndRetrieval(with: .shared)
         basicStorageAndRetrieval(with: .groupContainer("test"))
@@ -230,7 +253,7 @@
         let bundlePath = Bundle.main.bundlePath
         var bundleName = "/" + bundlePath.components(separatedBy: "/").last!
         if let range = bundleName.range(of: ".", options: String.CompareOptions.backwards, range: nil, locale: nil) {
-            bundleName = bundleName.substring(to: range.lowerBound)
+            bundleName = String(bundleName[..<range.lowerBound])
         }
         if let xdg_data_home = getenv("XDG_DATA_HOME") {
             destPath = String(utf8String: xdg_data_home)! + bundleName + "/.cookies.shared"
@@ -238,7 +261,7 @@
             destPath = NSHomeDirectory() + "/.local/share" + bundleName + "/.cookies.shared"
         }
         let fm = FileManager.default
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: destPath, isDirectory: &isDir)
         XCTAssertTrue(exists)
         //Test by setting the environmental variable
@@ -251,7 +274,7 @@
         let exeName = "/xdgTestHelper/xdgTestHelper"
         #endif
 
-        task.launchPath = bundlePath.substring(to: pathIndex!) + exeName
+        task.launchPath = bundlePath[..<pathIndex!] + exeName
         var environment = ProcessInfo.processInfo.environment
         let testPath = NSHomeDirectory() + "/TestXDG"
         environment["XDG_DATA_HOME"] = testPath
diff --git a/TestFoundation/TestJSONEncoder.swift b/TestFoundation/TestJSONEncoder.swift
index 8631442..76dc81a 100644
--- a/TestFoundation/TestJSONEncoder.swift
+++ b/TestFoundation/TestJSONEncoder.swift
@@ -401,6 +401,34 @@
         test_codingOf(value: URL(string: "https://swift.org")!, toAndFrom: "\"https://swift.org\"")
     }
 
+
+    // UInt and Int
+    func test_codingOfUIntMinMax() {
+
+        struct MyValue: Codable {
+            let int64Min = Int64.min
+            let int64Max = Int64.max
+            let uint64Min = UInt64.min
+            let uint64Max = UInt64.max
+        }
+
+        func compareJSON(_ s1: String, _ s2: String) {
+            let ss1 = s1.trimmingCharacters(in: CharacterSet(charactersIn: "{}")).split(separator: Character(",")).sorted()
+            let ss2 = s2.trimmingCharacters(in: CharacterSet(charactersIn: "{}")).split(separator: Character(",")).sorted()
+            XCTAssertEqual(ss1, ss2)
+        }
+
+        do {
+            let encoder = JSONEncoder()
+            let myValue = MyValue()
+            let result = try encoder.encode(myValue)
+            let r = String(data: result, encoding: .utf8) ?? "nil"
+            compareJSON(r, "{\"uint64Min\":0,\"uint64Max\":18446744073709551615,\"int64Min\":-9223372036854775808,\"int64Max\":9223372036854775807}")
+        } catch {
+            XCTFail(String(describing: error))
+        }
+    }
+
     // MARK: - Helper Functions
     private var _jsonEmptyDictionary: Data {
         return "{}".data(using: .utf8)!
@@ -418,8 +446,8 @@
                                    outputFormatting: JSONEncoder.OutputFormatting = [],
                                    dateEncodingStrategy: JSONEncoder.DateEncodingStrategy = .deferredToDate,
                                    dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate,
-                                   dataEncodingStrategy: JSONEncoder.DataEncodingStrategy = .base64Encode,
-                                   dataDecodingStrategy: JSONDecoder.DataDecodingStrategy = .base64Decode,
+                                   dataEncodingStrategy: JSONEncoder.DataEncodingStrategy = .base64,
+                                   dataDecodingStrategy: JSONDecoder.DataDecodingStrategy = .base64,
                                    nonConformingFloatEncodingStrategy: JSONEncoder.NonConformingFloatEncodingStrategy = .throw,
                                    nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy = .throw) where T : Codable, T : Equatable {
         var payload: Data! = nil
@@ -986,6 +1014,7 @@
             ("test_codingOfUInt64", test_codingOfUInt64),
             ("test_codingOfInt", test_codingOfInt),
             ("test_codingOfUInt", test_codingOfUInt),
+            ("test_codingOfUIntMinMax", test_codingOfUIntMinMax),
             ("test_codingOfFloat", test_codingOfFloat),
             ("test_codingOfDouble", test_codingOfDouble),
             ("test_codingOfString", test_codingOfString),
diff --git a/TestFoundation/TestJSONSerialization.swift b/TestFoundation/TestJSONSerialization.swift
index f381524..dabcf7f 100644
--- a/TestFoundation/TestJSONSerialization.swift
+++ b/TestFoundation/TestJSONSerialization.swift
@@ -829,6 +829,7 @@
         return [
             ("test_isValidJSONObjectTrue", test_isValidJSONObjectTrue),
             ("test_isValidJSONObjectFalse", test_isValidJSONObjectFalse),
+            ("test_validNumericJSONObjects", test_validNumericJSONObjects)
         ]
     }
 
@@ -924,6 +925,36 @@
         }
     }
 
+    func test_validNumericJSONObjects() {
+        // All of the numeric types supported by JSONSerialization
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([nil, NSNull()]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([true, false]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([Int.min, Int8.min, Int16.min, Int32.min, Int64.min]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([UInt.min, UInt8.min, UInt16.min, UInt32.min, UInt64.min]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([Float.leastNonzeroMagnitude, Double.leastNonzeroMagnitude]))
+
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: true), NSNumber(value: Float.greatestFiniteMagnitude), NSNumber(value: Double.greatestFiniteMagnitude)]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: Int.max), NSNumber(value: Int8.max), NSNumber(value: Int16.max), NSNumber(value: Int32.max), NSNumber(value: Int64.max)]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: UInt.max), NSNumber(value: UInt8.max), NSNumber(value: UInt16.max), NSNumber(value: UInt32.max), NSNumber(value: UInt64.max)]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([NSDecimalNumber(booleanLiteral: true), NSDecimalNumber(decimal: Decimal.greatestFiniteMagnitude), NSDecimalNumber(floatLiteral: Double.greatestFiniteMagnitude), NSDecimalNumber(integerLiteral: Int.min)]))
+        XCTAssertTrue(JSONSerialization.isValidJSONObject([Decimal(123), Decimal(Double.leastNonzeroMagnitude)]))
+
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(Float.nan))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(Float.infinity))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(-Float.infinity))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Float.nan)))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Float.infinity)))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: -Float.infinity)))
+
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(Double.nan))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(Double.infinity))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(-Double.infinity))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Double.nan)))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Double.infinity)))
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: -Double.infinity)))
+
+        XCTAssertFalse(JSONSerialization.isValidJSONObject(NSDecimalNumber(decimal: Decimal(floatLiteral: Double.nan))))
+    }
 }
 
 // MARK: - serializationTests
@@ -941,16 +972,24 @@
             ("test_serialize_IntMin", test_serialize_IntMin),
             ("test_serialize_UIntMax", test_serialize_UIntMax),
             ("test_serialize_UIntMin", test_serialize_UIntMin),
+            ("test_serialize_8BitSizes", test_serialize_8BitSizes),
+            ("test_serialize_16BitSizes", test_serialize_16BitSizes),
+            ("test_serialize_32BitSizes", test_serialize_32BitSizes),
+            ("test_serialize_64BitSizes", test_serialize_64BitSizes),
+            ("test_serialize_Float", test_serialize_Float),
+            ("test_serialize_Double", test_serialize_Double),
+            ("test_serialize_Decimal", test_serialize_Decimal),
+            ("test_serialize_NSDecimalNumber", test_serialize_NSDecimalNumber),
             ("test_serialize_stringEscaping", test_serialize_stringEscaping),
             ("test_jsonReadingOffTheEndOfBuffers", test_jsonReadingOffTheEndOfBuffers),
             ("test_jsonObjectToOutputStreamBuffer", test_jsonObjectToOutputStreamBuffer),
             ("test_jsonObjectToOutputStreamFile", test_jsonObjectToOutputStreamFile),
-            ("test_invalidJsonObjectToStreamBuffer", test_invalidJsonObjectToStreamBuffer),
             ("test_jsonObjectToOutputStreamInsufficientBuffer", test_jsonObjectToOutputStreamInsufficientBuffer),
             ("test_booleanJSONObject", test_booleanJSONObject),
             ("test_serialize_dictionaryWithDecimal", test_serialize_dictionaryWithDecimal),
             ("test_serializeDecimalNumberJSONObject", test_serializeDecimalNumberJSONObject),
             ("test_serializeSortedKeys", test_serializeSortedKeys),
+            ("test_serializePrettyPrinted", test_serializePrettyPrinted),
         ]
     }
 
@@ -1173,7 +1212,80 @@
         let json: [Any] = [UInt.min]
         XCTAssertEqual(try trySerialize(json), "[\(UInt.min)]")
     }
-    
+
+    func test_serialize_8BitSizes() {
+        let json1 = [Int8.min, Int8(-1), Int8(0), Int8(1), Int8.max]
+        XCTAssertEqual(try trySerialize(json1), "[-128,-1,0,1,127]")
+        let json2 = [UInt8.min, UInt8(0), UInt8(1), UInt8.max]
+        XCTAssertEqual(try trySerialize(json2), "[0,0,1,255]")
+    }
+
+    func test_serialize_16BitSizes() {
+        let json1 = [Int16.min, Int16(-1), Int16(0), Int16(1), Int16.max]
+        XCTAssertEqual(try trySerialize(json1), "[-32768,-1,0,1,32767]")
+        let json2 = [UInt16.min, UInt16(0), UInt16(1), UInt16.max]
+        XCTAssertEqual(try trySerialize(json2), "[0,0,1,65535]")
+    }
+
+    func test_serialize_32BitSizes() {
+        let json1 = [Int32.min, Int32(-1), Int32(0), Int32(1), Int32.max]
+        XCTAssertEqual(try trySerialize(json1), "[-2147483648,-1,0,1,2147483647]")
+        let json2 = [UInt32.min, UInt32(0), UInt32(1), UInt32.max]
+        XCTAssertEqual(try trySerialize(json2), "[0,0,1,4294967295]")
+    }
+
+    func test_serialize_64BitSizes() {
+        let json1 = [Int64.min, Int64(-1), Int64(0), Int64(1), Int64.max]
+        XCTAssertEqual(try trySerialize(json1), "[-9223372036854775808,-1,0,1,9223372036854775807]")
+        let json2 = [UInt64.min, UInt64(0), UInt64(1), UInt64.max]
+        XCTAssertEqual(try trySerialize(json2), "[0,0,1,18446744073709551615]")
+    }
+
+    func test_serialize_Float() {
+        XCTAssertEqual(try trySerialize([-Float.leastNonzeroMagnitude, Float.leastNonzeroMagnitude]), "[-0,0]")
+        XCTAssertEqual(try trySerialize([-Float.greatestFiniteMagnitude]), "[-340282346638529000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Float.greatestFiniteMagnitude]), "[340282346638529000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Float(-1), Float.leastNonzeroMagnitude, Float(1)]), "[-1,0,1]")
+    }
+
+    func test_serialize_Double() {
+        XCTAssertEqual(try trySerialize([-Double.leastNonzeroMagnitude, Double.leastNonzeroMagnitude]), "[-0,0]")
+        XCTAssertEqual(try trySerialize([-Double.leastNormalMagnitude, Double.leastNormalMagnitude]), "[-0,0]")
+        XCTAssertEqual(try trySerialize([-Double.greatestFiniteMagnitude]), "[-179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Double.greatestFiniteMagnitude]), "[179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Double(-1.0),  Double(1.0)]), "[-1,1]")
+    }
+
+    func test_serialize_Decimal() {
+        XCTAssertEqual(try trySerialize([-Decimal.leastFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Decimal.leastFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
+        XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
+        XCTAssertEqual(try trySerialize([-Decimal.greatestFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Decimal.greatestFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([Decimal(Int8.min), Decimal(Int8(0)), Decimal(Int8.max)]), "[-128,0,127]")
+        XCTAssertEqual(try trySerialize([Decimal(string: "-0.0"), Decimal(string: "0.000"), Decimal(string: "1.0000")]), "[0,0,1]")
+    }
+
+    func test_serialize_NSDecimalNumber() {
+        let dn0: [Any] = [NSDecimalNumber(floatLiteral: -Double.leastNonzeroMagnitude)]
+        let dn1: [Any] = [NSDecimalNumber(floatLiteral: Double.leastNonzeroMagnitude)]
+        let dn2: [Any] = [NSDecimalNumber(floatLiteral: -Double.leastNormalMagnitude)]
+        let dn3: [Any] = [NSDecimalNumber(floatLiteral: Double.leastNormalMagnitude)]
+        let dn4: [Any] = [NSDecimalNumber(floatLiteral: -Double.greatestFiniteMagnitude)]
+        let dn5: [Any] = [NSDecimalNumber(floatLiteral: Double.greatestFiniteMagnitude)]
+
+        XCTAssertEqual(try trySerialize(dn0), "[-0.00000000000000000000000000000000000000000000000000000000000000000004940656458412464128]")
+        XCTAssertEqual(try trySerialize(dn1), "[0.00000000000000000000000000000000000000000000000000000000000000000004940656458412464128]")
+        XCTAssertEqual(try trySerialize(dn2), "[-0.0000000000000000000000000000000000000000000000000002225073858507201792]")
+        XCTAssertEqual(try trySerialize(dn3), "[0.0000000000000000000000000000000000000000000000000002225073858507201792]")
+        XCTAssertEqual(try trySerialize(dn4), "[-17976931348623167488000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize(dn5), "[17976931348623167488000000000000000000000000000000000]")
+        XCTAssertEqual(try trySerialize([NSDecimalNumber(string: "0.0001"), NSDecimalNumber(string: "0.00"), NSDecimalNumber(string: "-0.0")]), "[0.0001,0,0]")
+        XCTAssertEqual(try trySerialize([NSDecimalNumber(integerLiteral: Int(Int16.min)), NSDecimalNumber(integerLiteral: 0), NSDecimalNumber(integerLiteral: Int(Int16.max))]), "[-32768,0,32767]")
+        XCTAssertEqual(try trySerialize([NSDecimalNumber(booleanLiteral: true), NSDecimalNumber(booleanLiteral: false)]), "[1,0]")
+    }
+
     func test_serialize_stringEscaping() {
         var json = ["foo"]
         XCTAssertEqual(try trySerialize(json), "[\"foo\"]")
@@ -1315,14 +1427,6 @@
         }
     }
     
-    func test_invalidJsonObjectToStreamBuffer() {
-        let str = "Invalid JSON"
-        let buffer = Array<UInt8>(repeating: 0, count: 10)
-        let outputStream = OutputStream(toBuffer: UnsafeMutablePointer(mutating: buffer), capacity: buffer.count)
-        outputStream.open()
-        XCTAssertThrowsError(try JSONSerialization.writeJSONObject(str, toStream: outputStream, options: []))
-    }
-    
     func test_booleanJSONObject() {
         do {
             let objectLikeBoolArray = try JSONSerialization.data(withJSONObject: [true, NSNumber(value: false), NSNumber(value: true)] as Array<Any>)
@@ -1376,6 +1480,11 @@
         XCTAssertEqual(try trySerialize(dict, options: .sortedKeys), "{\"a\":{\"a\":1,\"b\":1,\"c\":1},\"b\":{\"a\":1,\"b\":1,\"c\":1},\"c\":{\"a\":1,\"b\":1,\"c\":1}}")
     }
 
+    func test_serializePrettyPrinted() {
+        let dictionary = ["key": 4]
+        XCTAssertEqual(try trySerialize(dictionary, options: .prettyPrinted), "{\n  \"key\" : 4\n}")
+    }
+
     fileprivate func createTestFile(_ path: String,_contents: Data) -> String? {
         let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
diff --git a/TestFoundation/TestNSData.swift b/TestFoundation/TestNSData.swift
index 020b2c1..3bacd6e 100644
--- a/TestFoundation/TestNSData.swift
+++ b/TestFoundation/TestNSData.swift
@@ -17,7 +17,171 @@
 
 class TestNSData: XCTestCase {
     
-
+    class AllOnesImmutableData : NSData {
+        private var _length : Int
+        var _pointer : UnsafeMutableBufferPointer<UInt8>? {
+            willSet {
+                if let p = _pointer { free(p.baseAddress) }
+            }
+        }
+        
+        init(length : Int) {
+            _length = length
+            super.init(bytes: nil, length: 0, copy: false, deallocator: nil)
+            _length = length
+        }
+        
+        required init?(coder aDecoder: NSCoder) {
+            // Not tested
+            fatalError()
+        }
+        
+        deinit {
+            if let p = _pointer {
+                free(p.baseAddress)
+            }
+        }
+        
+        override var length : Int {
+            get {
+                return _length
+            }
+        }
+        
+        override var bytes : UnsafeRawPointer {
+            if let d = _pointer {
+                return UnsafeRawPointer(d.baseAddress!)
+            } else {
+                // Need to allocate the buffer now.
+                // It doesn't matter if the buffer is uniquely referenced or not here.
+                let buffer = malloc(length)
+                memset(buffer!, 1, length)
+                let bytePtr = buffer!.bindMemory(to: UInt8.self, capacity: length)
+                let result = UnsafeMutableBufferPointer(start: bytePtr, count: length)
+                _pointer = result
+                return UnsafeRawPointer(result.baseAddress!)
+            }
+        }
+        
+        override func getBytes(_ buffer: UnsafeMutableRawPointer, length: Int) {
+            if let d = _pointer {
+                // Get the real data from the buffer
+                memmove(buffer, d.baseAddress!, length)
+            } else {
+                // A more efficient implementation of getBytes in the case where no one has asked for our backing bytes
+                memset(buffer, 1, length)
+            }
+        }
+        
+        override func copy(with zone: NSZone? = nil) -> Any {
+            return self
+        }
+        
+        override func mutableCopy(with zone: NSZone? = nil) -> Any {
+            return AllOnesData(length: _length)
+        }
+    }
+    
+    
+    class AllOnesData : NSMutableData {
+        
+        private var _length : Int
+        var _pointer : UnsafeMutableBufferPointer<UInt8>? {
+            willSet {
+                if let p = _pointer { free(p.baseAddress) }
+            }
+        }
+        
+        /*override*/ init(length : Int) {
+            _length = length
+            super.init(bytes: nil, length: 0, copy: false, deallocator: nil)
+            _length = length
+        }
+        
+        required init?(coder aDecoder: NSCoder) {
+            // Not tested
+            fatalError()
+        }
+        
+        deinit {
+            if let p = _pointer {
+                free(p.baseAddress)
+            }
+        }
+        
+        override var length : Int {
+            get {
+                return _length
+            }
+            set {
+                if let ptr = _pointer {
+                    // Copy the data to our new length buffer
+                    let newBuffer = malloc(newValue)!
+                    if newValue <= _length {
+                        memmove(newBuffer, ptr.baseAddress!, newValue)
+                    } else if newValue > _length {
+                        memmove(newBuffer, ptr.baseAddress!, _length)
+                        memset(newBuffer + _length, 1, newValue - _length)
+                    }
+                    let bytePtr = newBuffer.bindMemory(to: UInt8.self, capacity: newValue)
+                    _pointer = UnsafeMutableBufferPointer(start: bytePtr, count: newValue)
+                }
+                _length = newValue
+            }
+        }
+        
+        override var bytes : UnsafeRawPointer {
+            if let d = _pointer {
+                return UnsafeRawPointer(d.baseAddress!)
+            } else {
+                // Need to allocate the buffer now.
+                // It doesn't matter if the buffer is uniquely referenced or not here.
+                let buffer = malloc(length)
+                memset(buffer!, 1, length)
+                let bytePtr = buffer!.bindMemory(to: UInt8.self, capacity: length)
+                let result = UnsafeMutableBufferPointer(start: bytePtr, count: length)
+                _pointer = result
+                return UnsafeRawPointer(result.baseAddress!)
+            }
+        }
+        
+        override var mutableBytes: UnsafeMutableRawPointer {
+            let newBufferLength = _length
+            let newBuffer = malloc(newBufferLength)
+            if let ptr = _pointer {
+                // Copy the existing data to the new box, then return its pointer
+                memmove(newBuffer!, ptr.baseAddress!, newBufferLength)
+            } else {
+                // Set new data to 1s
+                memset(newBuffer!, 1, newBufferLength)
+            }
+            let bytePtr = newBuffer!.bindMemory(to: UInt8.self, capacity: newBufferLength)
+            let result = UnsafeMutableBufferPointer(start: bytePtr, count: newBufferLength)
+            _pointer = result
+            _length = newBufferLength
+            return UnsafeMutableRawPointer(result.baseAddress!)
+        }
+        
+        override func getBytes(_ buffer: UnsafeMutableRawPointer, length: Int) {
+            if let d = _pointer {
+                // Get the real data from the buffer
+                memmove(buffer, d.baseAddress!, length)
+            } else {
+                // A more efficient implementation of getBytes in the case where no one has asked for our backing bytes
+                memset(buffer, 1, length)
+            }
+        }
+    }
+    
+    var heldData: Data?
+    
+    // this holds a reference while applying the function which forces the internal ref type to become non-uniquely referenced
+    func holdReference(_ data: Data, apply: () -> Void) {
+        heldData = data
+        apply()
+        heldData = nil
+    }
+    
     // MARK: -
     
     // String of course has its own way to get data, but this way tests our own data struct
@@ -37,6 +201,8 @@
             ("test_base64Data_medium", test_base64Data_medium),
             ("test_base64Data_small", test_base64Data_small),
             ("test_openingNonExistentFile", test_openingNonExistentFile),
+            ("test_contentsOfFile", test_contentsOfFile),
+            ("test_contentsOfZeroFile", test_contentsOfZeroFile),
             ("test_basicReadWrite", test_basicReadWrite),
             ("test_bufferSizeCalculation", test_bufferSizeCalculation),
             // ("test_dataHash", test_dataHash),   Disabled due to lack of brdiging in swift runtime -- infinite loops
@@ -98,6 +264,250 @@
             ("test_replaceSubrange", test_replaceSubrange),
             ("test_sliceWithUnsafeBytes", test_sliceWithUnsafeBytes),
             ("test_sliceIteration", test_sliceIteration),
+
+            ("test_validateMutation_withUnsafeMutableBytes", test_validateMutation_withUnsafeMutableBytes),
+            ("test_validateMutation_appendBytes", test_validateMutation_appendBytes),
+            ("test_validateMutation_appendData", test_validateMutation_appendData),
+            ("test_validateMutation_appendBuffer", test_validateMutation_appendBuffer),
+            ("test_validateMutation_appendSequence", test_validateMutation_appendSequence),
+            ("test_validateMutation_appendContentsOf", test_validateMutation_appendContentsOf),
+            ("test_validateMutation_resetBytes", test_validateMutation_resetBytes),
+            ("test_validateMutation_replaceSubrange", test_validateMutation_replaceSubrange),
+            ("test_validateMutation_replaceSubrangeCountableRange", test_validateMutation_replaceSubrangeCountableRange),
+            ("test_validateMutation_replaceSubrangeWithBuffer", test_validateMutation_replaceSubrangeWithBuffer),
+            ("test_validateMutation_replaceSubrangeWithCollection", test_validateMutation_replaceSubrangeWithCollection),
+            ("test_validateMutation_replaceSubrangeWithBytes", test_validateMutation_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_withUnsafeMutableBytes", test_validateMutation_slice_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_appendBytes", test_validateMutation_slice_appendBytes),
+            ("test_validateMutation_slice_appendData", test_validateMutation_slice_appendData),
+            ("test_validateMutation_slice_appendBuffer", test_validateMutation_slice_appendBuffer),
+            ("test_validateMutation_slice_appendSequence", test_validateMutation_slice_appendSequence),
+            ("test_validateMutation_slice_appendContentsOf", test_validateMutation_slice_appendContentsOf),
+            ("test_validateMutation_slice_resetBytes", test_validateMutation_slice_resetBytes),
+            ("test_validateMutation_slice_replaceSubrange", test_validateMutation_slice_replaceSubrange),
+            ("test_validateMutation_slice_replaceSubrangeCountableRange", test_validateMutation_slice_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_replaceSubrangeWithBuffer", test_validateMutation_slice_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_replaceSubrangeWithCollection", test_validateMutation_slice_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_replaceSubrangeWithBytes", test_validateMutation_slice_replaceSubrangeWithBytes),
+            ("test_validateMutation_cow_withUnsafeMutableBytes", test_validateMutation_cow_withUnsafeMutableBytes),
+            ("test_validateMutation_cow_appendBytes", test_validateMutation_cow_appendBytes),
+            ("test_validateMutation_cow_appendData", test_validateMutation_cow_appendData),
+            ("test_validateMutation_cow_appendBuffer", test_validateMutation_cow_appendBuffer),
+            ("test_validateMutation_cow_appendSequence", test_validateMutation_cow_appendSequence),
+            ("test_validateMutation_cow_appendContentsOf", test_validateMutation_cow_appendContentsOf),
+            ("test_validateMutation_cow_resetBytes", test_validateMutation_cow_resetBytes),
+            ("test_validateMutation_cow_replaceSubrange", test_validateMutation_cow_replaceSubrange),
+            ("test_validateMutation_cow_replaceSubrangeCountableRange", test_validateMutation_cow_replaceSubrangeCountableRange),
+            ("test_validateMutation_cow_replaceSubrangeWithBuffer", test_validateMutation_cow_replaceSubrangeWithBuffer),
+            ("test_validateMutation_cow_replaceSubrangeWithCollection", test_validateMutation_cow_replaceSubrangeWithCollection),
+            ("test_validateMutation_cow_replaceSubrangeWithBytes", test_validateMutation_cow_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_cow_withUnsafeMutableBytes", test_validateMutation_slice_cow_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_cow_appendBytes", test_validateMutation_slice_cow_appendBytes),
+            ("test_validateMutation_slice_cow_appendData", test_validateMutation_slice_cow_appendData),
+            ("test_validateMutation_slice_cow_appendBuffer", test_validateMutation_slice_cow_appendBuffer),
+            ("test_validateMutation_slice_cow_appendSequence", test_validateMutation_slice_cow_appendSequence),
+            ("test_validateMutation_slice_cow_appendContentsOf", test_validateMutation_slice_cow_appendContentsOf),
+            ("test_validateMutation_slice_cow_resetBytes", test_validateMutation_slice_cow_resetBytes),
+            ("test_validateMutation_slice_cow_replaceSubrange", test_validateMutation_slice_cow_replaceSubrange),
+            ("test_validateMutation_slice_cow_replaceSubrangeCountableRange", test_validateMutation_slice_cow_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_cow_replaceSubrangeWithBuffer", test_validateMutation_slice_cow_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_cow_replaceSubrangeWithCollection", test_validateMutation_slice_cow_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_cow_replaceSubrangeWithBytes", test_validateMutation_slice_cow_replaceSubrangeWithBytes),
+            ("test_validateMutation_immutableBacking_withUnsafeMutableBytes", test_validateMutation_immutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_immutableBacking_appendBytes", test_validateMutation_immutableBacking_appendBytes),
+            ("test_validateMutation_immutableBacking_appendData", test_validateMutation_immutableBacking_appendData),
+            ("test_validateMutation_immutableBacking_appendBuffer", test_validateMutation_immutableBacking_appendBuffer),
+            ("test_validateMutation_immutableBacking_appendSequence", test_validateMutation_immutableBacking_appendSequence),
+            ("test_validateMutation_immutableBacking_appendContentsOf", test_validateMutation_immutableBacking_appendContentsOf),
+            ("test_validateMutation_immutableBacking_resetBytes", test_validateMutation_immutableBacking_resetBytes),
+            ("test_validateMutation_immutableBacking_replaceSubrange", test_validateMutation_immutableBacking_replaceSubrange),
+            ("test_validateMutation_immutableBacking_replaceSubrangeCountableRange", test_validateMutation_immutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_immutableBacking_replaceSubrangeWithBuffer", test_validateMutation_immutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_immutableBacking_replaceSubrangeWithCollection", test_validateMutation_immutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_immutableBacking_replaceSubrangeWithBytes", test_validateMutation_immutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_immutableBacking_appendBytes", test_validateMutation_slice_immutableBacking_appendBytes),
+            ("test_validateMutation_slice_immutableBacking_appendData", test_validateMutation_slice_immutableBacking_appendData),
+            ("test_validateMutation_slice_immutableBacking_appendBuffer", test_validateMutation_slice_immutableBacking_appendBuffer),
+            ("test_validateMutation_slice_immutableBacking_appendSequence", test_validateMutation_slice_immutableBacking_appendSequence),
+            ("test_validateMutation_slice_immutableBacking_appendContentsOf", test_validateMutation_slice_immutableBacking_appendContentsOf),
+            ("test_validateMutation_slice_immutableBacking_resetBytes", test_validateMutation_slice_immutableBacking_resetBytes),
+            ("test_validateMutation_slice_immutableBacking_replaceSubrange", test_validateMutation_slice_immutableBacking_replaceSubrange),
+            ("test_validateMutation_slice_immutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_immutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_immutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_immutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_immutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_immutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_immutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_immutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_cow_immutableBacking_withUnsafeMutableBytes", test_validateMutation_cow_immutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_cow_immutableBacking_appendBytes", test_validateMutation_cow_immutableBacking_appendBytes),
+            ("test_validateMutation_cow_immutableBacking_appendData", test_validateMutation_cow_immutableBacking_appendData),
+            ("test_validateMutation_cow_immutableBacking_appendBuffer", test_validateMutation_cow_immutableBacking_appendBuffer),
+            ("test_validateMutation_cow_immutableBacking_appendSequence", test_validateMutation_cow_immutableBacking_appendSequence),
+            ("test_validateMutation_cow_immutableBacking_appendContentsOf", test_validateMutation_cow_immutableBacking_appendContentsOf),
+            ("test_validateMutation_cow_immutableBacking_resetBytes", test_validateMutation_cow_immutableBacking_resetBytes),
+            ("test_validateMutation_cow_immutableBacking_replaceSubrange", test_validateMutation_cow_immutableBacking_replaceSubrange),
+            ("test_validateMutation_cow_immutableBacking_replaceSubrangeCountableRange", test_validateMutation_cow_immutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_cow_immutableBacking_replaceSubrangeWithBuffer", test_validateMutation_cow_immutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_cow_immutableBacking_replaceSubrangeWithCollection", test_validateMutation_cow_immutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_cow_immutableBacking_replaceSubrangeWithBytes", test_validateMutation_cow_immutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_cow_immutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_cow_immutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_cow_immutableBacking_appendBytes", test_validateMutation_slice_cow_immutableBacking_appendBytes),
+            ("test_validateMutation_slice_cow_immutableBacking_appendData", test_validateMutation_slice_cow_immutableBacking_appendData),
+            ("test_validateMutation_slice_cow_immutableBacking_appendBuffer", test_validateMutation_slice_cow_immutableBacking_appendBuffer),
+            ("test_validateMutation_slice_cow_immutableBacking_appendSequence", test_validateMutation_slice_cow_immutableBacking_appendSequence),
+            ("test_validateMutation_slice_cow_immutableBacking_appendContentsOf", test_validateMutation_slice_cow_immutableBacking_appendContentsOf),
+            ("test_validateMutation_slice_cow_immutableBacking_resetBytes", test_validateMutation_slice_cow_immutableBacking_resetBytes),
+            ("test_validateMutation_slice_cow_immutableBacking_replaceSubrange", test_validateMutation_slice_cow_immutableBacking_replaceSubrange),
+            ("test_validateMutation_slice_cow_immutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_cow_immutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_mutableBacking_withUnsafeMutableBytes", test_validateMutation_mutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_mutableBacking_appendBytes", test_validateMutation_mutableBacking_appendBytes),
+            ("test_validateMutation_mutableBacking_appendData", test_validateMutation_mutableBacking_appendData),
+            ("test_validateMutation_mutableBacking_appendBuffer", test_validateMutation_mutableBacking_appendBuffer),
+            ("test_validateMutation_mutableBacking_appendSequence", test_validateMutation_mutableBacking_appendSequence),
+            ("test_validateMutation_mutableBacking_appendContentsOf", test_validateMutation_mutableBacking_appendContentsOf),
+            ("test_validateMutation_mutableBacking_resetBytes", test_validateMutation_mutableBacking_resetBytes),
+            ("test_validateMutation_mutableBacking_replaceSubrange", test_validateMutation_mutableBacking_replaceSubrange),
+            ("test_validateMutation_mutableBacking_replaceSubrangeCountableRange", test_validateMutation_mutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_mutableBacking_replaceSubrangeWithBuffer", test_validateMutation_mutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_mutableBacking_replaceSubrangeWithCollection", test_validateMutation_mutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_mutableBacking_replaceSubrangeWithBytes", test_validateMutation_mutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_mutableBacking_appendBytes", test_validateMutation_slice_mutableBacking_appendBytes),
+            ("test_validateMutation_slice_mutableBacking_appendData", test_validateMutation_slice_mutableBacking_appendData),
+            ("test_validateMutation_slice_mutableBacking_appendBuffer", test_validateMutation_slice_mutableBacking_appendBuffer),
+            ("test_validateMutation_slice_mutableBacking_appendSequence", test_validateMutation_slice_mutableBacking_appendSequence),
+            ("test_validateMutation_slice_mutableBacking_appendContentsOf", test_validateMutation_slice_mutableBacking_appendContentsOf),
+            ("test_validateMutation_slice_mutableBacking_resetBytes", test_validateMutation_slice_mutableBacking_resetBytes),
+            ("test_validateMutation_slice_mutableBacking_replaceSubrange", test_validateMutation_slice_mutableBacking_replaceSubrange),
+            ("test_validateMutation_slice_mutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_mutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_mutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_mutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_mutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_mutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_mutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_mutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_cow_mutableBacking_withUnsafeMutableBytes", test_validateMutation_cow_mutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_cow_mutableBacking_appendBytes", test_validateMutation_cow_mutableBacking_appendBytes),
+            ("test_validateMutation_cow_mutableBacking_appendData", test_validateMutation_cow_mutableBacking_appendData),
+            ("test_validateMutation_cow_mutableBacking_appendBuffer", test_validateMutation_cow_mutableBacking_appendBuffer),
+            ("test_validateMutation_cow_mutableBacking_appendSequence", test_validateMutation_cow_mutableBacking_appendSequence),
+            ("test_validateMutation_cow_mutableBacking_appendContentsOf", test_validateMutation_cow_mutableBacking_appendContentsOf),
+            ("test_validateMutation_cow_mutableBacking_resetBytes", test_validateMutation_cow_mutableBacking_resetBytes),
+            ("test_validateMutation_cow_mutableBacking_replaceSubrange", test_validateMutation_cow_mutableBacking_replaceSubrange),
+            ("test_validateMutation_cow_mutableBacking_replaceSubrangeCountableRange", test_validateMutation_cow_mutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_cow_mutableBacking_replaceSubrangeWithBuffer", test_validateMutation_cow_mutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_cow_mutableBacking_replaceSubrangeWithCollection", test_validateMutation_cow_mutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_cow_mutableBacking_replaceSubrangeWithBytes", test_validateMutation_cow_mutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_slice_cow_mutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_cow_mutableBacking_withUnsafeMutableBytes),
+            ("test_validateMutation_slice_cow_mutableBacking_appendBytes", test_validateMutation_slice_cow_mutableBacking_appendBytes),
+            ("test_validateMutation_slice_cow_mutableBacking_appendData", test_validateMutation_slice_cow_mutableBacking_appendData),
+            ("test_validateMutation_slice_cow_mutableBacking_appendBuffer", test_validateMutation_slice_cow_mutableBacking_appendBuffer),
+            ("test_validateMutation_slice_cow_mutableBacking_appendSequence", test_validateMutation_slice_cow_mutableBacking_appendSequence),
+            ("test_validateMutation_slice_cow_mutableBacking_appendContentsOf", test_validateMutation_slice_cow_mutableBacking_appendContentsOf),
+            ("test_validateMutation_slice_cow_mutableBacking_resetBytes", test_validateMutation_slice_cow_mutableBacking_resetBytes),
+            ("test_validateMutation_slice_cow_mutableBacking_replaceSubrange", test_validateMutation_slice_cow_mutableBacking_replaceSubrange),
+            ("test_validateMutation_slice_cow_mutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_cow_mutableBacking_replaceSubrangeCountableRange),
+            ("test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBuffer),
+            ("test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithCollection),
+            ("test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBytes),
+            ("test_validateMutation_customBacking_withUnsafeMutableBytes", test_validateMutation_customBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_customBacking_appendBytes", test_validateMutation_customBacking_appendBytes),
+//            ("test_validateMutation_customBacking_appendData", test_validateMutation_customBacking_appendData),
+//            ("test_validateMutation_customBacking_appendBuffer", test_validateMutation_customBacking_appendBuffer),
+//            ("test_validateMutation_customBacking_appendSequence", test_validateMutation_customBacking_appendSequence),
+//            ("test_validateMutation_customBacking_appendContentsOf", test_validateMutation_customBacking_appendContentsOf),
+//            ("test_validateMutation_customBacking_resetBytes", test_validateMutation_customBacking_resetBytes),
+//            ("test_validateMutation_customBacking_replaceSubrange", test_validateMutation_customBacking_replaceSubrange),
+//            ("test_validateMutation_customBacking_replaceSubrangeCountableRange", test_validateMutation_customBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_customBacking_replaceSubrangeWithBuffer", test_validateMutation_customBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_customBacking_replaceSubrangeWithCollection", test_validateMutation_customBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_customBacking_replaceSubrangeWithBytes", test_validateMutation_customBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_slice_customBacking_withUnsafeMutableBytes", test_validateMutation_slice_customBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_slice_customBacking_appendBytes", test_validateMutation_slice_customBacking_appendBytes),
+//            ("test_validateMutation_slice_customBacking_appendData", test_validateMutation_slice_customBacking_appendData),
+//            ("test_validateMutation_slice_customBacking_appendBuffer", test_validateMutation_slice_customBacking_appendBuffer),
+//            ("test_validateMutation_slice_customBacking_appendSequence", test_validateMutation_slice_customBacking_appendSequence),
+//            ("test_validateMutation_slice_customBacking_appendContentsOf", test_validateMutation_slice_customBacking_appendContentsOf),
+//            ("test_validateMutation_slice_customBacking_resetBytes", test_validateMutation_slice_customBacking_resetBytes),
+//            ("test_validateMutation_slice_customBacking_replaceSubrange", test_validateMutation_slice_customBacking_replaceSubrange),
+//            ("test_validateMutation_slice_customBacking_replaceSubrangeCountableRange", test_validateMutation_slice_customBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_slice_customBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_customBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_slice_customBacking_replaceSubrangeWithCollection", test_validateMutation_slice_customBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_slice_customBacking_replaceSubrangeWithBytes", test_validateMutation_slice_customBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_cow_customBacking_withUnsafeMutableBytes", test_validateMutation_cow_customBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_cow_customBacking_appendBytes", test_validateMutation_cow_customBacking_appendBytes),
+//            ("test_validateMutation_cow_customBacking_appendData", test_validateMutation_cow_customBacking_appendData),
+//            ("test_validateMutation_cow_customBacking_appendBuffer", test_validateMutation_cow_customBacking_appendBuffer),
+//            ("test_validateMutation_cow_customBacking_appendSequence", test_validateMutation_cow_customBacking_appendSequence),
+//            ("test_validateMutation_cow_customBacking_appendContentsOf", test_validateMutation_cow_customBacking_appendContentsOf),
+//            ("test_validateMutation_cow_customBacking_resetBytes", test_validateMutation_cow_customBacking_resetBytes),
+//            ("test_validateMutation_cow_customBacking_replaceSubrange", test_validateMutation_cow_customBacking_replaceSubrange),
+//            ("test_validateMutation_cow_customBacking_replaceSubrangeCountableRange", test_validateMutation_cow_customBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_cow_customBacking_replaceSubrangeWithBuffer", test_validateMutation_cow_customBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_cow_customBacking_replaceSubrangeWithCollection", test_validateMutation_cow_customBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_cow_customBacking_replaceSubrangeWithBytes", test_validateMutation_cow_customBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_slice_cow_customBacking_withUnsafeMutableBytes", test_validateMutation_slice_cow_customBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_slice_cow_customBacking_appendBytes", test_validateMutation_slice_cow_customBacking_appendBytes),
+//            ("test_validateMutation_slice_cow_customBacking_appendData", test_validateMutation_slice_cow_customBacking_appendData),
+//            ("test_validateMutation_slice_cow_customBacking_appendBuffer", test_validateMutation_slice_cow_customBacking_appendBuffer),
+//            ("test_validateMutation_slice_cow_customBacking_appendSequence", test_validateMutation_slice_cow_customBacking_appendSequence),
+//            ("test_validateMutation_slice_cow_customBacking_appendContentsOf", test_validateMutation_slice_cow_customBacking_appendContentsOf),
+//            ("test_validateMutation_slice_cow_customBacking_resetBytes", test_validateMutation_slice_cow_customBacking_resetBytes),
+//            ("test_validateMutation_slice_cow_customBacking_replaceSubrange", test_validateMutation_slice_cow_customBacking_replaceSubrange),
+//            ("test_validateMutation_slice_cow_customBacking_replaceSubrangeCountableRange", test_validateMutation_slice_cow_customBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_slice_cow_customBacking_replaceSubrangeWithCollection", test_validateMutation_slice_cow_customBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBytes", test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_customMutableBacking_withUnsafeMutableBytes", test_validateMutation_customMutableBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_customMutableBacking_appendBytes", test_validateMutation_customMutableBacking_appendBytes),
+//            ("test_validateMutation_customMutableBacking_appendData", test_validateMutation_customMutableBacking_appendData),
+//            ("test_validateMutation_customMutableBacking_appendBuffer", test_validateMutation_customMutableBacking_appendBuffer),
+//            ("test_validateMutation_customMutableBacking_appendSequence", test_validateMutation_customMutableBacking_appendSequence),
+//            ("test_validateMutation_customMutableBacking_appendContentsOf", test_validateMutation_customMutableBacking_appendContentsOf),
+//            ("test_validateMutation_customMutableBacking_resetBytes", test_validateMutation_customMutableBacking_resetBytes),
+//            ("test_validateMutation_customMutableBacking_replaceSubrange", test_validateMutation_customMutableBacking_replaceSubrange),
+//            ("test_validateMutation_customMutableBacking_replaceSubrangeCountableRange", test_validateMutation_customMutableBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_customMutableBacking_replaceSubrangeWithBuffer", test_validateMutation_customMutableBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_customMutableBacking_replaceSubrangeWithCollection", test_validateMutation_customMutableBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_customMutableBacking_replaceSubrangeWithBytes", test_validateMutation_customMutableBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_slice_customMutableBacking_appendBytes", test_validateMutation_slice_customMutableBacking_appendBytes),
+//            ("test_validateMutation_slice_customMutableBacking_appendData", test_validateMutation_slice_customMutableBacking_appendData),
+//            ("test_validateMutation_slice_customMutableBacking_appendBuffer", test_validateMutation_slice_customMutableBacking_appendBuffer),
+//            ("test_validateMutation_slice_customMutableBacking_appendSequence", test_validateMutation_slice_customMutableBacking_appendSequence),
+//            ("test_validateMutation_slice_customMutableBacking_appendContentsOf", test_validateMutation_slice_customMutableBacking_appendContentsOf),
+//            ("test_validateMutation_slice_customMutableBacking_resetBytes", test_validateMutation_slice_customMutableBacking_resetBytes),
+//            ("test_validateMutation_slice_customMutableBacking_replaceSubrange", test_validateMutation_slice_customMutableBacking_replaceSubrange),
+//            ("test_validateMutation_slice_customMutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_customMutableBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_slice_customMutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_customMutableBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_cow_customMutableBacking_withUnsafeMutableBytes", test_validateMutation_cow_customMutableBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_cow_customMutableBacking_appendBytes", test_validateMutation_cow_customMutableBacking_appendBytes),
+//            ("test_validateMutation_cow_customMutableBacking_appendData", test_validateMutation_cow_customMutableBacking_appendData),
+//            ("test_validateMutation_cow_customMutableBacking_appendBuffer", test_validateMutation_cow_customMutableBacking_appendBuffer),
+//            ("test_validateMutation_cow_customMutableBacking_appendSequence", test_validateMutation_cow_customMutableBacking_appendSequence),
+//            ("test_validateMutation_cow_customMutableBacking_appendContentsOf", test_validateMutation_cow_customMutableBacking_appendContentsOf),
+//            ("test_validateMutation_cow_customMutableBacking_resetBytes", test_validateMutation_cow_customMutableBacking_resetBytes),
+//            ("test_validateMutation_cow_customMutableBacking_replaceSubrange", test_validateMutation_cow_customMutableBacking_replaceSubrange),
+//            ("test_validateMutation_cow_customMutableBacking_replaceSubrangeCountableRange", test_validateMutation_cow_customMutableBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBuffer", test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_cow_customMutableBacking_replaceSubrangeWithCollection", test_validateMutation_cow_customMutableBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBytes", test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBytes),
+//            ("test_validateMutation_slice_cow_customMutableBacking_withUnsafeMutableBytes", test_validateMutation_slice_cow_customMutableBacking_withUnsafeMutableBytes),
+//            ("test_validateMutation_slice_cow_customMutableBacking_appendBytes", test_validateMutation_slice_cow_customMutableBacking_appendBytes),
+//            ("test_validateMutation_slice_cow_customMutableBacking_appendData", test_validateMutation_slice_cow_customMutableBacking_appendData),
+//            ("test_validateMutation_slice_cow_customMutableBacking_appendBuffer", test_validateMutation_slice_cow_customMutableBacking_appendBuffer),
+//            ("test_validateMutation_slice_cow_customMutableBacking_appendSequence", test_validateMutation_slice_cow_customMutableBacking_appendSequence),
+//            ("test_validateMutation_slice_cow_customMutableBacking_appendContentsOf", test_validateMutation_slice_cow_customMutableBacking_appendContentsOf),
+//            ("test_validateMutation_slice_cow_customMutableBacking_resetBytes", test_validateMutation_slice_cow_customMutableBacking_resetBytes),
+//            ("test_validateMutation_slice_cow_customMutableBacking_replaceSubrange", test_validateMutation_slice_cow_customMutableBacking_replaceSubrange),
+//            ("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeCountableRange", test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeCountableRange),
+//            ("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBuffer", test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBuffer),
+//            ("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithCollection", test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithCollection),
+//            ("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes", test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes),
+            ("test_sliceHash", test_sliceHash),
+            ("test_slice_resize_growth", test_slice_resize_growth),
+//            ("test_sliceEnumeration", test_sliceEnumeration),
         ]
     }
     
@@ -908,6 +1318,47 @@
         XCTAssertTrue(didCatchError)
     }
 
+    func test_contentsOfFile() {
+        let testDir = testBundle().resourcePath
+        let filename = testDir!.appending("/NSStringTestData.txt")
+
+        let contents = NSData(contentsOfFile: filename)
+        XCTAssertNotNil(contents)
+        if let contents = contents {
+            let ptr =  UnsafeMutableRawPointer(mutating: contents.bytes)
+            let str = String(bytesNoCopy: ptr, length: contents.length,
+                         encoding: .ascii, freeWhenDone: false)
+            XCTAssertEqual(str, "swift-corelibs-foundation")
+        }
+    }
+
+    func test_contentsOfZeroFile() {
+#if os(Linux)
+        guard FileManager.default.fileExists(atPath: "/proc/self") else {
+            return
+        }
+        let contents = NSData(contentsOfFile: "/proc/self/cmdline")
+        XCTAssertNotNil(contents)
+        if let contents = contents {
+            XCTAssertTrue(contents.length > 0)
+            let ptr = UnsafeMutableRawPointer(mutating: contents.bytes)
+            let str = String(bytesNoCopy: ptr, length: contents.length,
+                             encoding: .ascii, freeWhenDone: false)
+            XCTAssertNotNil(str)
+            if let str = str {
+                XCTAssertTrue(str.hasSuffix("TestFoundation"))
+            }
+        }
+
+        do {
+            let maps = try String(contentsOfFile: "/proc/self/maps", encoding: .utf8)
+            XCTAssertTrue(maps.count > 0)
+        } catch {
+            XCTFail("Cannot read /proc/self/maps: \(String(describing: error))")
+        }
+#endif
+    }
+
     func test_basicReadWrite() {
         let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent("testfile")
         let count = 1 << 24
@@ -1121,5 +1572,2385 @@
         XCTAssertEqual(found[0], 2)
         XCTAssertEqual(found[1], 3)
     }
+
+        func test_validateMutation_withUnsafeMutableBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 5).pointee = 0xFF
+        }
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9]))
+    }
+    
+    func test_validateMutation_appendBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        data.append("hello", count: 5)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0x5)
+    }
+    
+    func test_validateMutation_appendData() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let other = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        data.append(other)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+    }
+    
+    func test_validateMutation_appendBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+    }
+    
+    func test_validateMutation_appendSequence() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let seq = repeatElement(UInt8(1), count: 10)
+        data.append(contentsOf: seq)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 1)
+    }
+    
+    func test_validateMutation_appendContentsOf() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        data.append(contentsOf: bytes)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+    }
+    
+    func test_validateMutation_resetBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 0, 0, 0, 8, 9]))
+    }
+    
+    func test_validateMutation_replaceSubrange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_replaceSubrangeCountableRange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_replaceSubrangeWithBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer {
+            data.replaceSubrange(range, with: $0)
+        }
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_replaceSubrangeWithCollection() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with: bytes)
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_replaceSubrangeWithBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBytes {
+            data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+        }
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_slice_withUnsafeMutableBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 1).pointee = 0xFF
+        }
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 6, 7, 8]))
+    }
+    
+    func test_validateMutation_slice_appendBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_appendData() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let other = Data(bytes: [0xFF, 0xFF])
+        data.append(other)
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_appendBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_appendSequence() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let seq = repeatElement(UInt8(0xFF), count: 2)
+        data.append(contentsOf: seq)
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_appendContentsOf() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        data.append(contentsOf: bytes)
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_resetBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+    }
+    
+    func test_validateMutation_slice_replaceSubrange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_replaceSubrangeCountableRange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_replaceSubrangeWithBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer {
+            data.replaceSubrange(range, with: $0)
+        }
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_replaceSubrangeWithCollection() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with: bytes)
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_replaceSubrangeWithBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBytes {
+            data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+        }
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_cow_withUnsafeMutableBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 5).pointee = 0xFF
+            }
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_appendBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            data.append("hello", count: 5)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 0x9)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x68)
+        }
+    }
+    
+    func test_validateMutation_cow_appendData() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let other = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+            data.append(other)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_appendBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_appendSequence() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let seq = repeatElement(UInt8(1), count: 10)
+            data.append(contentsOf: seq)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 1)
+        }
+    }
+    
+    func test_validateMutation_cow_appendContentsOf() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_resetBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 0, 0, 0, 8, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_replaceSubrange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_replaceSubrangeCountableRange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_replaceSubrangeWithBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer {
+                data.replaceSubrange(range, with: $0)
+            }
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_replaceSubrangeWithCollection() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.replaceSubrange(range, with: bytes)
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+        }
+    }
+    
+    func test_validateMutation_cow_replaceSubrangeWithBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+            }
+            XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 0xFF, 0xFF, 9]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_withUnsafeMutableBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 1).pointee = 0xFF
+            }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 6, 7, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_appendBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            data.append("hello", count: 5)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 4)], 0x8)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0x68)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_appendData() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let other = Data(bytes: [0xFF, 0xFF])
+            data.append(other)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_appendBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_appendSequence() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let seq = repeatElement(UInt8(0xFF), count: 2)
+            data.append(contentsOf: seq)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_appendContentsOf() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_resetBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_replaceSubrange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_replaceSubrangeCountableRange() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_replaceSubrangeWithBuffer() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer {
+                data.replaceSubrange(range, with: $0)
+            }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_replaceSubrangeWithCollection() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.replaceSubrange(range, with: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_replaceSubrangeWithBytes() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+            }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_immutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 5).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+    }
+    
+    func test_validateMutation_immutableBacking_appendBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append("hello", count: 5)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0x68)
+    }
+    
+    func test_validateMutation_immutableBacking_appendData() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let other = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+        data.append(other)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0)
+    }
+    
+    func test_validateMutation_immutableBacking_appendBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0)
+    }
+    
+    func test_validateMutation_immutableBacking_appendSequence() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let seq = repeatElement(UInt8(1), count: 10)
+        data.append(contentsOf: seq)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 1)
+    }
+    
+    func test_validateMutation_immutableBacking_appendContentsOf() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        data.append(contentsOf: bytes)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0)
+    }
+    
+    func test_validateMutation_immutableBacking_resetBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x00, 0x72, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_immutableBacking_replaceSubrange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xFF, 0xFF, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_immutableBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xFF, 0xFF, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_immutableBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer {
+            data.replaceSubrange(range, with: $0)
+        }
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xFF, 0xFF, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_immutableBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with: bytes)
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xFF, 0xFF, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_immutableBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with: bytes)
+        XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xFF, 0xFF, 0x6c, 0x64]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))[4..<9]
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 1).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+    }
+    
+    func test_validateMutation_slice_immutableBacking_appendBytes() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_appendData() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_appendBuffer() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_appendSequence() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_appendContentsOf() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_resetBytes() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_replaceSubrange() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_replaceSubrangeCountableRange() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_replaceSubrangeWithBuffer() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        replacement.withUnsafeBufferPointer { (buffer: UnsafeBufferPointer<UInt8>) in
+            data.replaceSubrange(range, with: buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_replaceSubrangeWithCollection() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with:replacement)
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_slice_immutableBacking_replaceSubrangeWithBytes() {
+        let base: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = base.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        replacement.withUnsafeBytes {
+            data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+        }
+        XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+    }
+    
+    func test_validateMutation_cow_immutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 5).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_appendBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            data.append("hello", count: 5)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0x68)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_appendData() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let other = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+            data.append(other)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_appendBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_appendSequence() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let seq = repeatElement(UInt8(1), count: 10)
+            data.append(contentsOf: seq)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 1)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_appendContentsOf() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let bytes: [UInt8] = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x64)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 11)], 1)
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_resetBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x00, 0x72, 0x6c, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_replaceSubrange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            replacement.withUnsafeBufferPointer { (buffer: UnsafeBufferPointer<UInt8>) in
+                data.replaceSubrange(range, with: buffer)
+            }
+            XCTAssertEqual(data, Data(bytes: [0x68, 0xff, 0xff, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0xff, 0xff, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_cow_immutableBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        holdReference(data) {
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            replacement.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+            }
+            XCTAssertEqual(data, Data(bytes: [0x68, 0xff, 0xff, 0x64]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))[4..<9]
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 1).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_appendBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_appendData() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_appendBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer{ data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [0x6f, 0x20, 0x77, 0x6f, 0x72, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_appendSequence() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let bytes = repeatElement(UInt8(0xFF), count: 2)
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_appendContentsOf() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_resetBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_replaceSubrange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_replaceSubrangeCountableRange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBuffer() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithCollection() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.replaceSubrange(range, with: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_immutableBacking_replaceSubrangeWithBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))[4..<9]
+        }
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBytes { data.replaceSubrange(range, with: $0.baseAddress!, count: 2) }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_mutableBacking_withUnsafeMutableBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 5).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+    }
+    
+    func test_validateMutation_mutableBacking_appendBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_mutableBacking_appendData() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_mutableBacking_appendBuffer() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_mutableBacking_appendSequence() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_mutableBacking_appendContentsOf() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_mutableBacking_resetBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [0, 1, 2, 3, 4, 0, 0, 0, 8, 9]))
+    }
+    
+    func test_validateMutation_mutableBacking_replaceSubrange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_mutableBacking_replaceSubrangeCountableRange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement = Data(bytes: [0xFF, 0xFF])
+        data.replaceSubrange(range, with: replacement)
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_mutableBacking_replaceSubrangeWithBuffer() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer {
+            data.replaceSubrange(range, with: $0)
+        }
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_mutableBacking_replaceSubrangeWithCollection() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_mutableBacking_replaceSubrangeWithBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var data = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        data.append(contentsOf: [7, 8, 9])
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBytes {
+            data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count)
+        }
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 9]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_withUnsafeMutableBytes() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 1).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+    }
+    
+    func test_validateMutation_slice_mutableBacking_appendBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_appendData() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_appendBuffer() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let bytes: [UInt8] = [1, 2, 3]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0x20, 0x77, 0x6f, 0x72, 0x1, 0x2, 0x3]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_appendSequence() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let seq = repeatElement(UInt8(1), count: 3)
+        data.append(contentsOf: seq)
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0x20, 0x77, 0x6f, 0x72, 0x1, 0x1, 0x1]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_appendContentsOf() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let bytes: [UInt8] = [1, 2, 3]
+        data.append(contentsOf: bytes)
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0x20, 0x77, 0x6f, 0x72, 0x1, 0x2, 0x3]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_resetBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_replaceSubrange() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0xFF, 0xFF, 0x72]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_replaceSubrangeCountableRange() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0xFF, 0xFF, 0x72]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_replaceSubrangeWithBuffer() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        replacement.withUnsafeBufferPointer { (buffer: UnsafeBufferPointer<UInt8>) in
+            data.replaceSubrange(range, with: buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0xFF, 0xFF, 0x72]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_replaceSubrangeWithCollection() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        data.replaceSubrange(range, with:replacement)
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0xFF, 0xFF, 0x72]))
+    }
+    
+    func test_validateMutation_slice_mutableBacking_replaceSubrangeWithBytes() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        let replacement: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        replacement.withUnsafeBytes {
+            data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+        }
+        XCTAssertEqual(data, Data(bytes: [0x6f, 0xFF, 0xFF, 0x72]))
+    }
+    
+    func test_validateMutation_cow_mutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 5).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_appendBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            data.append("hello", count: 5)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 16)], 6)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 17)], 0x68)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_appendData() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            data.append("hello", count: 5)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 16)], 6)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 17)], 0x68)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_appendBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let other = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+            data.append(other)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 16)], 6)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 17)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_appendSequence() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let seq = repeatElement(UInt8(1), count: 10)
+            data.append(contentsOf: seq)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 16)], 6)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 17)], 1)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_appendContentsOf() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let bytes: [UInt8] = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 16)], 6)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 17)], 1)
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_resetBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x00, 0x72, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_replaceSubrange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement = Data(bytes: [0xFF, 0xFF])
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            replacement.withUnsafeBufferPointer { (buffer: UnsafeBufferPointer<UInt8>) in
+                data.replaceSubrange(range, with: buffer)
+            }
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            data.replaceSubrange(range, with: replacement)
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_cow_mutableBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: NSData(bytes: "hello world", length: 11))
+        data.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        holdReference(data) {
+            let replacement: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 4)..<data.startIndex.advanced(by: 9)
+            replacement.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: 2)
+            }
+            XCTAssertEqual(data, Data(bytes: [0x68, 0x65, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x64, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_withUnsafeMutableBytes() {
+        var base = Data(referencing: NSData(bytes: "hello world", length: 11))
+        base.append(contentsOf: [1, 2, 3, 4, 5, 6])
+        var data = base[4..<9]
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 1).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_appendBytes() {
+        let bytes: [UInt8] = [0, 1, 2]
+        var base = bytes.withUnsafeBytes { (ptr) in
+            return Data(referencing: NSData(bytes: ptr.baseAddress!, length: ptr.count))
+        }
+        base.append(contentsOf: [3, 4, 5])
+        var data = base[1..<4]
+        holdReference(data) {
+            let bytesToAppend: [UInt8] = [6, 7, 8]
+            bytesToAppend.withUnsafeBytes { (ptr) in
+                data.append(ptr.baseAddress!.assumingMemoryBound(to: UInt8.self), count: ptr.count)
+            }
+            XCTAssertEqual(data, Data(bytes: [1, 2, 3, 6, 7, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_appendData() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_appendBuffer() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer{ data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_appendSequence() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let bytes = repeatElement(UInt8(0xFF), count: 2)
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_appendContentsOf() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.append(contentsOf: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 8, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_resetBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [4, 0, 0, 0, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_replaceSubrange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_replaceSubrangeCountableRange() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: CountableRange<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBuffer() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithCollection() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            data.replaceSubrange(range, with: bytes)
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_mutableBacking_replaceSubrangeWithBytes() {
+        let baseBytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6]
+        var base = baseBytes.withUnsafeBufferPointer {
+            return Data(referencing: NSData(bytes: $0.baseAddress!, length: $0.count))
+        }
+        base.append(contentsOf: [7, 8, 9])
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Data.Index> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBytes { data.replaceSubrange(range, with: $0.baseAddress!, count: 2) }
+            XCTAssertEqual(data, Data(bytes: [4, 0xFF, 0xFF, 8]))
+        }
+    }
+    
+    func test_validateMutation_customBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 5).pointee = 0xFF
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 1, 1, 1, 1]))
+    }
+    
+#if false // this requires factory patterns
+    func test_validateMutation_customBacking_appendBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customBacking_appendData() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { (buffer) in
+            data.append(buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        
+    }
+    
+    func test_validateMutation_customBacking_appendSequence() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customBacking_resetBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0, 0, 0, 1, 1]))
+    }
+    
+    func test_validateMutation_customBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let range: Range<Int> = 1..<4
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1, 1, 1, 1, 1, 1]))
+    }
+    
+    func test_validateMutation_customBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let range: CountableRange<Int> = 1..<4
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1, 1, 1, 1, 1, 1]))
+    }
+    
+    func test_validateMutation_customBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Int> = 1..<4
+        bytes.withUnsafeBufferPointer { (buffer) in
+            data.replaceSubrange(range, with: buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1, 1, 1, 1, 1, 1]))
+    }
+    
+    func test_validateMutation_customBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let range: Range<Int> = 1..<4
+        data.replaceSubrange(range, with: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1, 1, 1, 1, 1, 1]))
+    }
+    
+    func test_validateMutation_customBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        let range: Range<Int> = 1..<5
+        bytes.withUnsafeBufferPointer { (buffer) in
+            data.replaceSubrange(range, with: buffer.baseAddress!, count: buffer.count)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1, 1, 1, 1, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 1).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+    }
+    
+    func test_validateMutation_slice_customBacking_appendBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBytes { ptr in
+            data.append(ptr.baseAddress!.assumingMemoryBound(to: UInt8.self), count: ptr.count)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customBacking_appendData() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { (buffer) in
+            data.append(buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customBacking_appendSequence() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let seq = repeatElement(UInt8(0xFF), count: 2)
+        data.append(contentsOf: seq)
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customBacking_resetBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { (buffer) in
+            data.replaceSubrange(range, with: buffer)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+    }
+    
+    func test_validateMutation_slice_customBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBytes { buffer in
+            data.replaceSubrange(range, with: buffer.baseAddress!, count: 2)
+        }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+    }
+    
+    func test_validateMutation_cow_customBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 5).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_appendBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { (buffer) in
+                data.append(buffer.baseAddress!, count: buffer.count)
+            }
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_appendData() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_appendSequence() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            data.append(contentsOf: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_resetBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0, 0, 0, 1, 1]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_cow_customBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            bytes.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count)
+            }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 1).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_appendBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { (buffer) in
+                data.append(buffer.baseAddress!, count: buffer.count)
+            }
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_appendData() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_appendSequence() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            data.append(contentsOf: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 1, 1, 1, 1, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_resetBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesImmutableData(length: 10))[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBytes {
+                data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count)
+            }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 1]))
+        }
+    }
+    
+    func test_validateMutation_customMutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 5).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+    }
+    
+    func test_validateMutation_customMutableBacking_appendBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customMutableBacking_appendData() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customMutableBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customMutableBacking_appendSequence() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customMutableBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_customMutableBacking_resetBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        data.resetBytes(in: 5..<8)
+        XCTAssertEqual(data.count, 10)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 0)], 1)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 6)], 0)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 7)], 0)
+    }
+    
+    func test_validateMutation_customMutableBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_customMutableBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_customMutableBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_customMutableBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_customMutableBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_withUnsafeMutableBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+            ptr.advanced(by: 1).pointee = 0xFF
+        }
+        XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_appendBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_appendData() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        data.append(Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_appendBuffer() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_appendSequence() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.append($0) }
+        XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_appendContentsOf() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        data.append(contentsOf: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_resetBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        data.resetBytes(in: 5..<8)
+        
+        XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 2)], 0)
+        XCTAssertEqual(data[data.startIndex.advanced(by: 3)], 0)
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_replaceSubrange() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_replaceSubrangeCountableRange() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBuffer() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_replaceSubrangeWithCollection() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        data.replaceSubrange(range, with: [0xFF, 0xFF])
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_slice_customMutableBacking_replaceSubrangeWithBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+        let bytes: [UInt8] = [0xFF, 0xFF]
+        bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count) }
+        XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_withUnsafeMutableBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 5).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_appendBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_appendData() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_appendBuffer() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_appendSequence() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_appendContentsOf() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            data.append(contentsOf: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_resetBytes() {
+        var data = Data(referencing: AllOnesData(length: 10))
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data.count, 10)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 0)], 1)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 6)], 0)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 7)], 0)
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_replaceSubrange() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0])) 
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_replaceSubrangeCountableRange() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0])) 
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBuffer() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0])) 
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_replaceSubrangeWithCollection() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0])) 
+        }
+    }
+    
+    func test_validateMutation_cow_customMutableBacking_replaceSubrangeWithBytes() {
+        var data = Data(referencing: AllOnesData(length: 1))
+        data.count = 10
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count) }
+            XCTAssertEqual(data, Data(bytes: [1, 0xFF, 0xFF, 0])) 
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_withUnsafeMutableBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
+                ptr.advanced(by: 1).pointee = 0xFF
+            }
+            XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0xFF)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_appendBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) }
+            XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_appendData() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            data.append(Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_appendBuffer() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.append($0) }
+            XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_appendSequence() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            data.append(contentsOf: repeatElement(UInt8(0xFF), count: 2))
+            XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_appendContentsOf() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            data.append(contentsOf: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [0, 0, 0, 0, 0, 0xFF, 0xFF]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_resetBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            data.resetBytes(in: 5..<8)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 1)], 0)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 2)], 0)
+            XCTAssertEqual(data[data.startIndex.advanced(by: 3)], 0)
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_replaceSubrange() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeCountableRange() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: CountableRange<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: Data(bytes: [0xFF, 0xFF]))
+            XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBuffer() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0) }
+            XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithCollection() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            data.replaceSubrange(range, with: [0xFF, 0xFF])
+            XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+        }
+    }
+    
+    func test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes() {
+        var base = Data(referencing: AllOnesData(length: 1))
+        base.count = 10
+        var data = base[4..<9]
+        holdReference(data) {
+            let range: Range<Int> = data.startIndex.advanced(by: 1)..<data.endIndex.advanced(by: -1)
+            let bytes: [UInt8] = [0xFF, 0xFF]
+            bytes.withUnsafeBufferPointer { data.replaceSubrange(range, with: $0.baseAddress!, count: $0.count) }
+            XCTAssertEqual(data, Data(bytes: [0, 0xFF, 0xFF, 0]))
+        }
+    }
+#endif
+    
+    func test_sliceHash() {
+        let base1 = Data(bytes: [0, 0xFF, 0xFF, 0])
+        let base2 = Data(bytes: [0, 0xFF, 0xFF, 0])
+        let base3 = Data(bytes: [0xFF, 0xFF, 0xFF, 0])
+        let sliceEmulation = Data(bytes: [0xFF, 0xFF])
+        XCTAssertEqual(base1.hashValue, base2.hashValue)
+        let slice1 = base1[base1.startIndex.advanced(by: 1)..<base1.endIndex.advanced(by: -1)]
+        let slice2 = base2[base2.startIndex.advanced(by: 1)..<base2.endIndex.advanced(by: -1)]
+        let slice3 = base3[base3.startIndex.advanced(by: 1)..<base3.endIndex.advanced(by: -1)]
+        XCTAssertEqual(slice1.hashValue, sliceEmulation.hashValue)
+        XCTAssertEqual(slice1.hashValue, slice2.hashValue)
+        XCTAssertEqual(slice2.hashValue, slice3.hashValue)
+    }
+
+    func test_slice_resize_growth() {
+        var data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9]
+        data.resetBytes(in: data.endIndex.advanced(by: -1)..<data.endIndex.advanced(by: 1))
+        XCTAssertEqual(data, Data(bytes: [4, 5, 6, 7, 0, 0]))
+    }
+    
+    /*
+    func test_sliceEnumeration() {
+        var base = DispatchData.empty
+        let bytes: [UInt8] = [0, 1, 2, 3, 4]
+        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
+        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
+        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
+        let data = ((base as AnyObject) as! Data)[3..<11]
+        var regionRanges: [Range<Int>] = []
+        var regionData: [Data] = []
+        data.enumerateBytes { (buffer, index, _) in
+            regionData.append(Data(bytes: buffer.baseAddress!, count: buffer.count))
+            regionRanges.append(index..<index + buffer.count)
+        }
+        XCTAssertEqual(regionRanges.count, 3)
+        XCTAssertEqual(Range<Data.Index>(3..<5), regionRanges[0])
+        XCTAssertEqual(Range<Data.Index>(5..<10), regionRanges[1])
+        XCTAssertEqual(Range<Data.Index>(10..<11), regionRanges[2])
+        XCTAssertEqual(Data(bytes: [3, 4]), regionData[0]) //fails
+        XCTAssertEqual(Data(bytes: [0, 1, 2, 3, 4]), regionData[1]) //passes
+        XCTAssertEqual(Data(bytes: [0]), regionData[2]) //fails
+    }
+ */
 }
 
diff --git a/TestFoundation/TestNSDictionary.swift b/TestFoundation/TestNSDictionary.swift
index 096f0a6..fa09cb0 100644
--- a/TestFoundation/TestNSDictionary.swift
+++ b/TestFoundation/TestNSDictionary.swift
@@ -211,7 +211,7 @@
             let d1: NSDictionary = ["Hello":["world":"again"]]
             let isWritten = d1.write(toFile: testFilePath!, atomically: true)
             if(isWritten) {
-                let dict = NSMutableDictionary.init(contentsOfFile: testFilePath!)
+                let dict = NSDictionary(contentsOfFile: testFilePath!)
                 XCTAssert(dict == d1)
             } else {
                 XCTFail("Write to file failed")
diff --git a/TestFoundation/TestNSGeometry.swift b/TestFoundation/TestNSGeometry.swift
index 3286cac..3c662f9 100644
--- a/TestFoundation/TestNSGeometry.swift
+++ b/TestFoundation/TestNSGeometry.swift
@@ -11,7 +11,6 @@
 #if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
     import Foundation
     import XCTest
-    import CoreFoundation
 #else
     import SwiftFoundation
     import SwiftXCTest
diff --git a/TestFoundation/TestNSKeyedArchiver.swift b/TestFoundation/TestNSKeyedArchiver.swift
index 32fd2b6..4ccc05e 100644
--- a/TestFoundation/TestNSKeyedArchiver.swift
+++ b/TestFoundation/TestNSKeyedArchiver.swift
@@ -106,6 +106,7 @@
             ("test_archive_user_class", test_archive_user_class),
             ("test_archive_uuid_bvref", test_archive_uuid_byref),
             ("test_archive_uuid_byvalue", test_archive_uuid_byvalue),
+            ("test_archive_unhashable", test_archive_unhashable),
         ]
     }
 
@@ -118,7 +119,7 @@
         XCTAssertTrue(encode(archiver))
         archiver.finishEncoding()
         
-        let unarchiver = NSKeyedUnarchiver(forReadingWithData: Data._unconditionallyBridgeFromObjectiveC(data))
+        let unarchiver = NSKeyedUnarchiver(forReadingWith: Data._unconditionallyBridgeFromObjectiveC(data))
         XCTAssertTrue(decode(unarchiver))
         
         // Archiving using the default initializer
@@ -127,10 +128,10 @@
         XCTAssertTrue(encode(archiver1))
         let archivedData = archiver1.encodedData
         
-        let unarchiver1 = NSKeyedUnarchiver(forReadingWithData: archivedData)
+        let unarchiver1 = NSKeyedUnarchiver(forReadingWith: archivedData)
         XCTAssertTrue(decode(unarchiver1))
     }
-    
+
     private func test_archive(_ object: Any, classes: [AnyClass], allowsSecureCoding: Bool = true, outputFormat: PropertyListSerialization.PropertyListFormat) {
         test_archive({ archiver -> Bool in
                 archiver.requiresSecureCoding = allowsSecureCoding
@@ -312,4 +313,30 @@
         let uuid = UUID()
         return test_archive(uuid, classes: [NSUUID.self])
     }
+
+    func test_archive_unhashable() {
+        let data = """
+            {
+              "args": {},
+              "headers": {
+                "Accept": "*/*",
+                "Accept-Encoding": "deflate, gzip",
+                "Accept-Language": "en",
+                "Connection": "close",
+                "Host": "httpbin.org",
+                "User-Agent": "TestFoundation (unknown version) curl/7.54.0"
+              },
+              "origin": "0.0.0.0",
+              "url": "https://httpbin.org/get"
+            }
+            """.data(using: .utf8)!
+        do {
+            let json = try JSONSerialization.jsonObject(with: data)
+            _ = NSKeyedArchiver.archivedData(withRootObject: json)
+            XCTAssert(true, "NSKeyedArchiver.archivedData handles unhashable")
+        }
+        catch {
+            XCTFail("test_archive_unhashable, de-serialization error \(error)")
+        }
+    }
 }
diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift
index d3ddde8..9d2ac9c 100644
--- a/TestFoundation/TestNSNumber.swift
+++ b/TestFoundation/TestNSNumber.swift
@@ -43,6 +43,8 @@
             ("test_description", test_description ),
             ("test_descriptionWithLocale", test_descriptionWithLocale ),
             ("test_objCType", test_objCType ),
+            ("test_stringValue", test_stringValue),
+            ("test_Equals", test_Equals),
         ]
     }
     
@@ -1019,4 +1021,141 @@
         XCTAssertEqual("f" /* 0x66 */, objCType(NSNumber(value: Float.greatestFiniteMagnitude)))
         XCTAssertEqual("d" /* 0x64 */, objCType(NSNumber(value: Double.greatestFiniteMagnitude)))
     }
+
+    func test_stringValue() {
+
+        if UInt.max == UInt32.max {
+            XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0")
+            XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1")
+            XCTAssertEqual(NSNumber(value: UInt.max).stringValue, "4294967295")
+            XCTAssertEqual(NSNumber(value: UInt.max - 1).stringValue, "4294967294")
+        } else if UInt.max == UInt64.max {
+            XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0")
+            XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1")
+            XCTAssertEqual(NSNumber(value: UInt.max).stringValue, "18446744073709551615")
+            XCTAssertEqual(NSNumber(value: UInt.max - 1).stringValue, "18446744073709551614")
+        }
+
+        XCTAssertEqual(NSNumber(value: UInt8.min).stringValue, "0")
+        XCTAssertEqual(NSNumber(value: UInt8.min + 1).stringValue, "1")
+        XCTAssertEqual(NSNumber(value: UInt8.max).stringValue, "255")
+        XCTAssertEqual(NSNumber(value: UInt8.max - 1).stringValue, "254")
+
+        XCTAssertEqual(NSNumber(value: UInt16.min).stringValue, "0")
+        XCTAssertEqual(NSNumber(value: UInt16.min + 1).stringValue, "1")
+        XCTAssertEqual(NSNumber(value: UInt16.max).stringValue, "65535")
+        XCTAssertEqual(NSNumber(value: UInt16.max - 1).stringValue, "65534")
+
+        XCTAssertEqual(NSNumber(value: UInt32.min).stringValue, "0")
+        XCTAssertEqual(NSNumber(value: UInt32.min + 1).stringValue, "1")
+        XCTAssertEqual(NSNumber(value: UInt32.max).stringValue, "4294967295")
+        XCTAssertEqual(NSNumber(value: UInt32.max - 1).stringValue, "4294967294")
+
+        XCTAssertEqual(NSNumber(value: UInt64.min).stringValue, "0")
+        XCTAssertEqual(NSNumber(value: UInt64.min + 1).stringValue, "1")
+        XCTAssertEqual(NSNumber(value: UInt64.max).stringValue, "18446744073709551615")
+        XCTAssertEqual(NSNumber(value: UInt64.max - 1).stringValue, "18446744073709551614")
+
+        if Int.max == Int32.max {
+            XCTAssertEqual(NSNumber(value: Int.min).stringValue, "-2147483648")
+            XCTAssertEqual(NSNumber(value: Int.min + 1).stringValue, "-2147483647")
+            XCTAssertEqual(NSNumber(value: Int.max).stringValue, "2147483647")
+            XCTAssertEqual(NSNumber(value: Int.max - 1).stringValue, "2147483646")
+        } else if Int.max == Int64.max {
+            XCTAssertEqual(NSNumber(value: Int.min).stringValue, "-9223372036854775808")
+            XCTAssertEqual(NSNumber(value: Int.min + 1).stringValue, "-9223372036854775807")
+            XCTAssertEqual(NSNumber(value: Int.max).stringValue, "9223372036854775807")
+            XCTAssertEqual(NSNumber(value: Int.max - 1).stringValue, "9223372036854775806")
+        }
+
+        XCTAssertEqual(NSNumber(value: Int8.min).stringValue, "-128")
+        XCTAssertEqual(NSNumber(value: Int8.min + 1).stringValue, "-127")
+        XCTAssertEqual(NSNumber(value: Int8.max).stringValue, "127")
+        XCTAssertEqual(NSNumber(value: Int8.max - 1).stringValue, "126")
+
+        XCTAssertEqual(NSNumber(value: Int16.min).stringValue, "-32768")
+        XCTAssertEqual(NSNumber(value: Int16.min + 1).stringValue, "-32767")
+        XCTAssertEqual(NSNumber(value: Int16.max).stringValue, "32767")
+        XCTAssertEqual(NSNumber(value: Int16.max - 1).stringValue, "32766")
+
+        XCTAssertEqual(NSNumber(value: Int32.min).stringValue, "-2147483648")
+        XCTAssertEqual(NSNumber(value: Int32.min + 1).stringValue, "-2147483647")
+        XCTAssertEqual(NSNumber(value: Int32.max).stringValue, "2147483647")
+        XCTAssertEqual(NSNumber(value: Int32.max - 1).stringValue, "2147483646")
+
+        XCTAssertEqual(NSNumber(value: Int64.min).stringValue, "-9223372036854775808")
+        XCTAssertEqual(NSNumber(value: Int64.min + 1).stringValue, "-9223372036854775807")
+        XCTAssertEqual(NSNumber(value: Int64.max).stringValue, "9223372036854775807")
+        XCTAssertEqual(NSNumber(value: Int64.max - 1).stringValue, "9223372036854775806")
+    }
+
+    func test_Equals() {
+        // Booleans: false only equals 0, true only equals 1
+        XCTAssertTrue(NSNumber(value: true) == NSNumber(value: Bool(true)))
+        XCTAssertTrue(NSNumber(value: true) == NSNumber(value: Int(1)))
+        XCTAssertTrue(NSNumber(value: true) == NSNumber(value: Float(1)))
+        XCTAssertTrue(NSNumber(value: true) == NSNumber(value: Double(1)))
+        XCTAssertTrue(NSNumber(value: true) == NSNumber(value: Int8(1)))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: false))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: Int8(-1)))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: Float(1.01)))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: Double(1234.56)))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: 2))
+        XCTAssertTrue(NSNumber(value: true) != NSNumber(value: Int.max))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: Bool(false)))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: Int(0)))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: Float(0)))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: Double(0)))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: Int8(0)))
+        XCTAssertTrue(NSNumber(value: false) == NSNumber(value: UInt64(0)))
+        XCTAssertTrue(NSNumber(value: false) != NSNumber(value: 1))
+        XCTAssertTrue(NSNumber(value: false) != NSNumber(value: 2))
+        XCTAssertTrue(NSNumber(value: false) != NSNumber(value: Int.max))
+
+        XCTAssertTrue(NSNumber(value: Int8(-1)) == NSNumber(value: Int16(-1)))
+        XCTAssertTrue(NSNumber(value: Int16(-1)) == NSNumber(value: Int32(-1)))
+        XCTAssertTrue(NSNumber(value: Int32(-1)) == NSNumber(value: Int64(-1)))
+        XCTAssertTrue(NSNumber(value: Int8.max) != NSNumber(value: Int16.max))
+        XCTAssertTrue(NSNumber(value: Int16.max) != NSNumber(value: Int32.max))
+        XCTAssertTrue(NSNumber(value: Int32.max) != NSNumber(value: Int64.max))
+        XCTAssertTrue(NSNumber(value: UInt8.min) == NSNumber(value: UInt16.min))
+        XCTAssertTrue(NSNumber(value: UInt16.min) == NSNumber(value: UInt32.min))
+        XCTAssertTrue(NSNumber(value: UInt32.min) == NSNumber(value: UInt64.min))
+        XCTAssertTrue(NSNumber(value: UInt8.max) != NSNumber(value: UInt16.max))
+        XCTAssertTrue(NSNumber(value: UInt16.max) != NSNumber(value: UInt32.max))
+        XCTAssertTrue(NSNumber(value: UInt32.max) != NSNumber(value: UInt64.max))
+        XCTAssertTrue(NSNumber(value: Int8(0)) == NSNumber(value: UInt16(0)))
+        XCTAssertTrue(NSNumber(value: UInt16(0)) == NSNumber(value: Int32(0)))
+        XCTAssertTrue(NSNumber(value: Int32(0)) == NSNumber(value: UInt64(0)))
+        XCTAssertTrue(NSNumber(value: Int(0)) == NSNumber(value: UInt(0)))
+        XCTAssertTrue(NSNumber(value: Int8.min) == NSNumber(value: Float(-128)))
+        XCTAssertTrue(NSNumber(value: Int8.max) == NSNumber(value: Double(127)))
+        XCTAssertTrue(NSNumber(value: UInt16.min) == NSNumber(value: Float(0)))
+        XCTAssertTrue(NSNumber(value: UInt16.max) == NSNumber(value: Double(65535)))
+        XCTAssertTrue(NSNumber(value: 1.1) != NSNumber(value: Int64(1)))
+        let num = NSNumber(value: Int8.min)
+        XCTAssertFalse(num == NSNumber(value: num.uint64Value))
+
+        let num1 = NSNumber(value: Float.nan)
+        XCTAssertEqual(num1.compare(num1), ComparisonResult.orderedSame)
+
+        let num2 = NSNumber(value: num1.uint8Value) // 0
+        XCTAssertFalse(num1 == num2)
+        XCTAssertFalse(num2 == num1)
+        XCTAssertEqual(num1.compare(num2), ComparisonResult.orderedAscending)
+        XCTAssertEqual(num2.compare(num1), ComparisonResult.orderedDescending)
+
+        let num3 = NSNumber(value: Double.nan)
+        XCTAssertEqual(num3.compare(num3), ComparisonResult.orderedSame)
+
+        let num4 = NSNumber(value: num3.intValue) // 0
+        XCTAssertFalse(num3 == num2)
+        XCTAssertFalse(num4 == num3)
+        XCTAssertEqual(num3.compare(num4), ComparisonResult.orderedAscending)
+        XCTAssertEqual(num4.compare(num3), ComparisonResult.orderedDescending)
+
+        XCTAssertEqual(NSNumber(value: Double.leastNonzeroMagnitude).compare(NSNumber(value: 0)), ComparisonResult.orderedDescending)
+        XCTAssertEqual(NSNumber(value: Double.greatestFiniteMagnitude).compare(NSNumber(value: 0)), ComparisonResult.orderedDescending)
+        XCTAssertTrue(NSNumber(value: Double(-0.0)) == NSNumber(value: Double(0.0)))
+    }
 }
diff --git a/TestFoundation/TestNSNumberBridging.swift b/TestFoundation/TestNSNumberBridging.swift
new file mode 100644
index 0000000..3edcbaf
--- /dev/null
+++ b/TestFoundation/TestNSNumberBridging.swift
@@ -0,0 +1,866 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+import Foundation
+import XCTest
+#else
+import SwiftFoundation
+import SwiftXCTest
+#endif
+
+class TestNSNumberBridging : XCTestCase {
+    static var allTests: [(String, (TestNSNumberBridging) -> () throws -> Void)] {
+        return [
+            ("testNSNumberBridgeFromInt8", testNSNumberBridgeFromInt8),
+            ("testNSNumberBridgeFromUInt8", testNSNumberBridgeFromUInt8),
+            ("testNSNumberBridgeFromInt16", testNSNumberBridgeFromInt16),
+            ("testNSNumberBridgeFromUInt16", testNSNumberBridgeFromUInt16),
+            ("testNSNumberBridgeFromInt32", testNSNumberBridgeFromInt32),
+            ("testNSNumberBridgeFromUInt32", testNSNumberBridgeFromUInt32),
+            ("testNSNumberBridgeFromInt64", testNSNumberBridgeFromInt64),
+            ("testNSNumberBridgeFromUInt64", testNSNumberBridgeFromUInt64),
+            ("testNSNumberBridgeFromInt", testNSNumberBridgeFromInt),
+            ("testNSNumberBridgeFromUInt", testNSNumberBridgeFromUInt),
+            ("testNSNumberBridgeFromFloat", testNSNumberBridgeFromFloat),
+            ("testNSNumberBridgeFromDouble", testNSNumberBridgeFromDouble),
+            ("test_numericBitPatterns_to_floatingPointTypes", test_numericBitPatterns_to_floatingPointTypes),
+            ("testNSNumberBridgeAnyHashable", testNSNumberBridgeAnyHashable),
+        ]
+    }
+
+    func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
+        let message = "\(file):\(line) \(String(describing: lhs)) != \(String(describing: rhs)) Float"
+        if let lhsValue = lhs {
+            if let rhsValue = rhs {
+                if lhsValue.isNaN != rhsValue.isNaN {
+                    XCTFail(message)
+                } else if lhsValue != rhsValue && !lhsValue.isNaN {
+                    XCTFail(message)
+                }
+            } else {
+                XCTFail(message)
+            }
+        } else {
+            if rhs != nil {
+                XCTFail(message)
+            }
+        }
+    }
+
+    func testDouble(_ lhs: Double?, _ rhs: Double?, file: String = #file, line: UInt = #line) {
+        let message = "\(file):\(line) \(String(describing: lhs)) != \(String(describing: rhs)) Double"
+        if let lhsValue = lhs {
+            if let rhsValue = rhs {
+                if lhsValue.isNaN != rhsValue.isNaN {
+                    XCTFail(message)
+                } else if lhsValue != rhsValue && !lhsValue.isNaN {
+                    XCTFail(message)
+                }
+            } else {
+                XCTFail(message)
+            }
+        } else {
+            if rhs != nil {
+                XCTFail(message)
+            }
+        }
+    }
+
+    func testNSNumberBridgeFromInt8() {
+        for interestingValue in Int8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt8() {
+        for interestingValue in UInt8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt16() {
+        for interestingValue in Int16._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt16() {
+        for interestingValue in UInt8._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt32() {
+        for interestingValue in Int32._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                let expectedFloat = Float(exactly: int32!)
+                // these are disabled because of https://bugs.swift.org/browse/SR-4634
+                if (int32! != Int32.min && int32! != Int32.max &&
+                    int32! != Int32.min + 1 && int32! != Int32.max - 1) {
+                    testFloat(expectedFloat, float)
+                }
+                let double = Double(exactly: number!)
+                let expectedDouble = Double(exactly: int32!)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt32() {
+        for interestingValue in UInt32._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                let expectedFloat = Float(exactly: uint32!)
+                // these are disabled because of https://bugs.swift.org/browse/SR-4634
+                if (uint32! != UInt32.max && uint32! != UInt32.max - 1) {
+                    testFloat(expectedFloat, float)
+                }
+                let double = Double(exactly: number!)
+                let expectedDouble = Double(exactly: uint32!)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt64() {
+        for interestingValue in Int64._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt64() {
+        for interestingValue in UInt64._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromInt() {
+        for interestingValue in Int._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromUInt() {
+        for interestingValue in UInt._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+                let float = Float(exactly: number!)
+                XCTAssertEqual(Float(interestingValue), float)
+                let double = Double(exactly: number!)
+                XCTAssertEqual(Double(interestingValue), double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromFloat() {
+        for interestingValue in Float._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+
+                let float = Float(truncating: number!)
+                let expectedFloat = interestingValue
+                testFloat(expectedFloat, float)
+
+                let double = Double(truncating: number!)
+                let expectedDouble = Double(reasonably: interestingValue)
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func testNSNumberBridgeFromDouble() {
+        for interestingValue in Double._interestingValues {
+            func testNumber(_ number: NSNumber?) {
+                XCTAssertNotNil(number)
+                let int8 = Int8(exactly: number!)
+                XCTAssertEqual(Int8(exactly: interestingValue), int8)
+                let uint8 = UInt8(exactly: number!)
+                XCTAssertEqual(UInt8(exactly: interestingValue), uint8)
+                let int16 = Int16(exactly: number!)
+                XCTAssertEqual(Int16(exactly: interestingValue), int16)
+                let uint16 = UInt16(exactly: number!)
+                XCTAssertEqual(UInt16(exactly: interestingValue), uint16)
+                let int32 = Int32(exactly: number!)
+                XCTAssertEqual(Int32(exactly: interestingValue), int32)
+                let uint32 = UInt32(exactly: number!)
+                XCTAssertEqual(UInt32(exactly: interestingValue), uint32)
+                let int64 = Int64(exactly: number!)
+                XCTAssertEqual(Int64(exactly: interestingValue), int64)
+                let uint64 = UInt64(exactly: number!)
+                XCTAssertEqual(UInt64(exactly: interestingValue), uint64)
+                let int = Int(exactly: number!)
+                XCTAssertEqual(Int(exactly: interestingValue), int)
+                let uint = UInt(exactly: number!)
+                XCTAssertEqual(UInt(exactly: interestingValue), uint)
+
+                let float = Float(truncating: number!)
+                let expectedFloat = Float(reasonably: interestingValue)
+                testFloat(expectedFloat, float)
+
+                let double = Double(exactly: number!)
+                let expectedDouble = interestingValue
+                testDouble(expectedDouble, double)
+            }
+            let bridged = interestingValue._bridgeToObjectiveC()
+            testNumber(bridged)
+            let created = NSNumber(value: interestingValue)
+            testNumber(created)
+        }
+    }
+
+    func test_numericBitPatterns_to_floatingPointTypes() {
+        let signed_numbers: [NSNumber] = [
+            NSNumber(value: Int64(6)),
+            NSNumber(value: Int64(bitPattern: 1 << 56)),
+            NSNumber(value: Int64(bitPattern: 1 << 53)),
+            NSNumber(value: Int64(bitPattern: 1 << 52)),
+            NSNumber(value: Int64(bitPattern: 1 << 25)),
+            NSNumber(value: Int64(bitPattern: 1 << 24)),
+            NSNumber(value: Int64(bitPattern: 1 << 23)),
+            NSNumber(value: -Int64(bitPattern: 1 << 53)),
+            NSNumber(value: -Int64(bitPattern: 1 << 52)),
+            NSNumber(value: -Int64(6)),
+            NSNumber(value: -Int64(bitPattern: 1 << 56)),
+            NSNumber(value: -Int64(bitPattern: 1 << 25)),
+            NSNumber(value: -Int64(bitPattern: 1 << 24)),
+            NSNumber(value: -Int64(bitPattern: 1 << 23)),
+            ]
+
+        let signed_values: [Int64] = [
+            Int64(6),
+            Int64(bitPattern: 1 << 56),
+            Int64(bitPattern: 1 << 53),
+            Int64(bitPattern: 1 << 52),
+            Int64(bitPattern: 1 << 25),
+            Int64(bitPattern: 1 << 24),
+            Int64(bitPattern: 1 << 23),
+            -Int64(bitPattern: 1 << 53),
+            -Int64(bitPattern: 1 << 52),
+            -Int64(6),
+            -Int64(bitPattern: 1 << 56),
+            -Int64(bitPattern: 1 << 25),
+            -Int64(bitPattern: 1 << 24),
+            -Int64(bitPattern: 1 << 23),
+            ]
+
+        let unsigned_numbers: [NSNumber] = [
+            NSNumber(value: UInt64(bitPattern: 6)),
+            NSNumber(value: UInt64(bitPattern: 1 << 56)),
+            NSNumber(value: UInt64(bitPattern: 1 << 63)),
+            NSNumber(value: UInt64(bitPattern: 1 << 53)),
+            NSNumber(value: UInt64(bitPattern: 1 << 52)),
+            NSNumber(value: UInt64(bitPattern: 1 << 25)),
+            NSNumber(value: UInt64(bitPattern: 1 << 24)),
+            NSNumber(value: UInt64(bitPattern: 1 << 23)),
+            ]
+
+        let unsigned_values: [UInt64] = [
+            UInt64(bitPattern: 6),
+            UInt64(bitPattern: 1 << 56),
+            UInt64(bitPattern: 1 << 63),
+            UInt64(bitPattern: 1 << 53),
+            UInt64(bitPattern: 1 << 52),
+            UInt64(bitPattern: 1 << 25),
+            UInt64(bitPattern: 1 << 24),
+            UInt64(bitPattern: 1 << 23)
+        ]
+
+        for (number, value) in zip(signed_numbers, signed_values) {
+            let numberCast = Double(exactly: number)
+            let valueCast = Double(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(unsigned_numbers, unsigned_values) {
+            let numberCast = Double(exactly: number)
+            let valueCast = Double(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(signed_numbers, signed_values) {
+            let numberCast = Float(exactly: number)
+            let valueCast = Float(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+
+        for (number, value) in zip(unsigned_numbers, unsigned_values) {
+            let numberCast = Float(exactly: number)
+            let valueCast = Float(exactly: value)
+            XCTAssertEqual(numberCast, valueCast)
+        }
+    }
+
+    func testNSNumberBridgeAnyHashable() {
+        var dict = [AnyHashable : Any]()
+        for i in -Int(UInt8.min) ... Int(UInt8.max) {
+            dict[i] = "\(i)"
+        }
+
+        // When bridging a dictionary to NSDictionary, we should be able to access
+        // the keys through either an Int (the original type boxed in AnyHashable)
+        // or NSNumber (the type Int bridged to).
+        let ns_dict = dict._bridgeToObjectiveC()
+        for i in -Int(UInt8.min) ... Int(UInt8.max) {
+            guard let value = ns_dict[i] as? String else {
+                XCTFail("Unable to look up value by Int key.")
+                continue
+            }
+
+            guard let ns_value = ns_dict[NSNumber(value: i)] as? String else {
+                XCTFail("Unable to look up value by NSNumber key.")
+                continue
+            }
+
+            XCTAssertEqual(value, ns_value)
+        }
+    }
+}
+
+extension Float {
+    init?(reasonably value: Float) {
+        self = value
+    }
+
+    init?(reasonably value: Double) {
+        guard !value.isNaN else {
+            self = Float.nan
+            return
+        }
+
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                self = -Float.infinity
+            } else {
+                self = Float.infinity
+            }
+            return
+        }
+
+        guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
+            return nil
+        }
+
+        self = Float(value)
+    }
+}
+
+extension Double {
+    init?(reasonably value: Float) {
+        guard !value.isNaN else {
+            self = Double.nan
+            return
+        }
+
+        guard !value.isInfinite else {
+            if value.sign == .minus {
+                self = -Double.infinity
+            } else {
+                self = Double.infinity
+            }
+            return
+        }
+
+        self = Double(value)
+    }
+
+    init?(reasonably value: Double) {
+        self = value
+    }
+}
+
+extension Int8 {
+    static var _interestingValues: [Int8] {
+        return [
+            Int8.min,
+            Int8.min + 1,
+            Int8.max,
+            Int8.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt8 {
+    static var _interestingValues: [UInt8] {
+        return [
+            UInt8.min,
+            UInt8.min + 1,
+            UInt8.max,
+            UInt8.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int16 {
+    static var _interestingValues: [Int16] {
+        return [
+            Int16.min,
+            Int16.min + 1,
+            Int16.max,
+            Int16.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt16 {
+    static var _interestingValues: [UInt16] {
+        return [
+            UInt16.min,
+            UInt16.min + 1,
+            UInt16.max,
+            UInt16.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int32 {
+    static var _interestingValues: [Int32] {
+        return [
+            Int32.min,
+            Int32.min + 1,
+            Int32.max,
+            Int32.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt32 {
+    static var _interestingValues: [UInt32] {
+        return [
+            UInt32.min,
+            UInt32.min + 1,
+            UInt32.max,
+            UInt32.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int64 {
+    static var _interestingValues: [Int64] {
+        return [
+            Int64.min,
+            Int64.min + 1,
+            Int64.max,
+            Int64.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt64 {
+    static var _interestingValues: [UInt64] {
+        return [
+            UInt64.min,
+            UInt64.min + 1,
+            UInt64.max,
+            UInt64.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Int {
+    static var _interestingValues: [Int] {
+        return [
+            Int.min,
+            Int.min + 1,
+            Int.max,
+            Int.max - 1,
+            0,
+            -1,
+            1,
+            -42,
+            42,
+        ]
+    }
+}
+
+extension UInt {
+    static var _interestingValues: [UInt] {
+        return [
+            UInt.min,
+            UInt.min + 1,
+            UInt.max,
+            UInt.max - 1,
+            42,
+        ]
+    }
+}
+
+extension Float {
+    static var _interestingValues: [Float] {
+        return [
+            -Float.infinity,
+            -Float.greatestFiniteMagnitude,
+            -1.0,
+            -Float.ulpOfOne,
+            -Float.leastNormalMagnitude,
+            -0.0,
+            0.0,
+            Float.leastNormalMagnitude,
+            Float.ulpOfOne,
+            1.0,
+            Float.greatestFiniteMagnitude,
+            Float.infinity,
+            Float.nan,
+        ]
+    }
+}
+
+extension Double {
+    static var _interestingValues: [Double] {
+        return [
+            -Double.infinity,
+            //-Double.greatestFiniteMagnitude,
+            -1.0,
+            -Double.ulpOfOne,
+            -Double.leastNormalMagnitude,
+            -0.0,
+            0.0,
+            Double.leastNormalMagnitude,
+            Double.ulpOfOne,
+            1.0,
+            //Double.greatestFiniteMagnitude,
+            Double.infinity,
+            Double.nan,
+        ]
+    }
+}
diff --git a/TestFoundation/TestNSRegularExpression.swift b/TestFoundation/TestNSRegularExpression.swift
index 8b115cc..aa7dfe1 100644
--- a/TestFoundation/TestNSRegularExpression.swift
+++ b/TestFoundation/TestNSRegularExpression.swift
@@ -28,6 +28,8 @@
             ("test_complexRegularExpressions", test_complexRegularExpressions),
             ("test_Equal", test_Equal),
             ("test_NSCoding", test_NSCoding),
+            ("test_defaultOptions", test_defaultOptions),
+            ("test_badPattern", test_badPattern),
         ]
     }
     
@@ -164,7 +166,7 @@
         simpleRegularExpressionTestWithPattern(NSRegularExpression.escapedPattern(for: "+\\{}[].^$?#<=!&*()"), target:"+\\{}[].^$?#<=!&*() abc", looking:true, match:false)
     }
     
-    func replaceRegularExpressionTest(_ patternString: String, _ patternOptions: NSRegularExpression.Options, _ searchString: String, _ searchOptions: NSMatchingOptions, _ searchRange: NSRange, _ templ: String, _ numberOfMatches: Int, _ result: String, file: StaticString = #file, line: UInt = #line) {
+    func replaceRegularExpressionTest(_ patternString: String, _ patternOptions: NSRegularExpression.Options, _ searchString: String, _ searchOptions: NSRegularExpression.MatchingOptions, _ searchRange: NSRange, _ templ: String, _ numberOfMatches: Int, _ result: String, file: StaticString = #file, line: UInt = #line) {
         do {
             let regex = try NSRegularExpression(pattern: patternString, options: patternOptions)
             let mutableString = NSMutableString(string: searchString)
@@ -205,7 +207,7 @@
         replaceRegularExpressionTest("([1-9]a)([1-9]b)([1-9]c)([1-9]d)([1-9]e)([1-9]f)([1-9]z)", [], "9a3b4c8d3e1f2z,9a3b4c8d3e1f2z", [], NSMakeRange(0,29), "$2$4$1 is your key", 2, "3b8d9a is your key,3b8d9a is your key")
     }
     
-    func complexRegularExpressionTest(_ patternString: String, _ patternOptions: NSRegularExpression.Options, _ searchString: String, _ searchOptions: NSMatchingOptions, _ searchRange: NSRange, _ numberOfMatches: Int, _ firstMatchOverallRange: NSRange, _ firstMatchFirstCaptureRange: NSRange, _ firstMatchLastCaptureRange: NSRange, file: StaticString = #file, line: UInt = #line) {
+    func complexRegularExpressionTest(_ patternString: String, _ patternOptions: NSRegularExpression.Options, _ searchString: String, _ searchOptions: NSRegularExpression.MatchingOptions, _ searchRange: NSRange, _ numberOfMatches: Int, _ firstMatchOverallRange: NSRange, _ firstMatchFirstCaptureRange: NSRange, _ firstMatchLastCaptureRange: NSRange, file: StaticString = #file, line: UInt = #line) {
         do {
             let regex = try NSRegularExpression(pattern: patternString, options: patternOptions)
             let matches = regex.matches(in: searchString, options: searchOptions, range: searchRange)
@@ -352,4 +354,33 @@
         let regularExpressionB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: regularExpressionA)) as! NSRegularExpression
         XCTAssertEqual(regularExpressionA, regularExpressionB, "Archived then unarchived `NSRegularExpression` must be equal.")
     }
+
+    // Check all of the following functions do not need to be passed options:
+    func test_defaultOptions() {
+        let pattern = ".*fatal error: (.*): file (.*), line ([0-9]+)$"
+        let text = "fatal error: Some message: file /tmp/foo.swift, line 123"
+        let regex = try? NSRegularExpression(pattern: pattern)
+        XCTAssertNotNil(regex)
+        let range = NSRange(text.startIndex..., in: text)
+        regex!.enumerateMatches(in: text, range: range, using: {_,_,_ in })
+        XCTAssertEqual(regex!.matches(in: text, range: range).first?.numberOfRanges, 4)
+        XCTAssertEqual(regex!.numberOfMatches(in: text, range: range), 1)
+        XCTAssertEqual(regex!.firstMatch(in: text, range: range)?.numberOfRanges, 4)
+        XCTAssertEqual(regex!.rangeOfFirstMatch(in: text, range: range),
+                       NSMakeRange(0, 56))
+        XCTAssertEqual(regex!.stringByReplacingMatches(in: text, range: range, withTemplate: "$1-$2-$3"),
+                      "Some message-/tmp/foo.swift-123")
+        let str = NSMutableString(string: text)
+        XCTAssertEqual(regex!.replaceMatches(in: str, range: range, withTemplate: "$1-$2-$3"), 1)
+    }
+
+    func test_badPattern() {
+        do {
+            _ = try NSRegularExpression(pattern: "(", options: [])
+            XCTFail()
+        } catch {
+            let err = String(describing: error)
+            XCTAssertEqual(err, "Error Domain=NSCocoaErrorDomain Code=2048 \"(null)\" UserInfo={NSInvalidValue=(}")
+        }
+    }
 }
diff --git a/TestFoundation/TestNSString.swift b/TestFoundation/TestNSString.swift
index 56e34fe..e75bd4f 100644
--- a/TestFoundation/TestNSString.swift
+++ b/TestFoundation/TestNSString.swift
@@ -66,6 +66,8 @@
             ("test_rangeOfCharacterFromSet", test_rangeOfCharacterFromSet ),
             ("test_CFStringCreateMutableCopy", test_CFStringCreateMutableCopy),
             ("test_FromContentsOfURL",test_FromContentsOfURL),
+            ("test_FromContentOfFileUsedEncodingIgnored", test_FromContentOfFileUsedEncodingIgnored),
+            ("test_FromContentOfFileUsedEncodingUTF8", test_FromContentOfFileUsedEncodingUTF8),
             ("test_FromContentsOfURLUsedEncodingUTF16BE", test_FromContentsOfURLUsedEncodingUTF16BE),
             ("test_FromContentsOfURLUsedEncodingUTF16LE", test_FromContentsOfURLUsedEncodingUTF16LE),
             ("test_FromContentsOfURLUsedEncodingUTF32BE", test_FromContentsOfURLUsedEncodingUTF32BE),
@@ -96,7 +98,6 @@
             ("test_mutableStringConstructor", test_mutableStringConstructor),
             ("test_emptyStringPrefixAndSuffix",test_emptyStringPrefixAndSuffix),
             ("test_PrefixSuffix", test_PrefixSuffix),
-            ("test_utf16StringRangeCount", test_StringUTF16ViewIndexStrideableRange),
             ("test_reflection", { _ in test_reflection }),
             ("test_replacingOccurrences", test_replacingOccurrences),
             ("test_getLineStart", test_getLineStart),
@@ -266,21 +267,21 @@
 
     func test_FromNullTerminatedCStringInASCII() {
         let bytes = mockASCIIStringBytes + [0x00]
-        let string = NSString(CString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.ascii.rawValue)
+        let string = NSString(cString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.ascii.rawValue)
         XCTAssertNotNil(string)
         XCTAssertTrue(string?.isEqual(to: mockASCIIString) ?? false)
     }
 
     func test_FromNullTerminatedCStringInUTF8() {
         let bytes = mockUTF8StringBytes + [0x00]
-        let string = NSString(CString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.utf8.rawValue)
+        let string = NSString(cString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.utf8.rawValue)
         XCTAssertNotNil(string)
         XCTAssertTrue(string?.isEqual(to: mockUTF8String) ?? false)
     }
 
     func test_FromMalformedNullTerminatedCStringInUTF8() {
         let bytes = mockMalformedUTF8StringBytes + [0x00]
-        let string = NSString(CString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.utf8.rawValue)
+        let string = NSString(cString: bytes.map { Int8(bitPattern: $0) }, encoding: String.Encoding.utf8.rawValue)
         XCTAssertNil(string)
     }
 
@@ -304,6 +305,32 @@
         }
     }
 
+    func test_FromContentOfFileUsedEncodingIgnored() {
+        let testFilePath = testBundle().path(forResource: "NSStringTestData", ofType: "txt")
+        XCTAssertNotNil(testFilePath)
+        
+        do {
+            let str = try NSString(contentsOfFile: testFilePath!, usedEncoding: nil)
+            XCTAssertEqual(str, "swift-corelibs-foundation")
+        } catch {
+            XCTFail("Unable to init NSString from contentsOfFile:encoding:")
+        }
+    }
+    
+    func test_FromContentOfFileUsedEncodingUTF8() {
+        let testFilePath = testBundle().path(forResource: "NSStringTestData", ofType: "txt")
+        XCTAssertNotNil(testFilePath)
+        
+        do {
+            var encoding: UInt = 0
+            let str = try NSString(contentsOfFile: testFilePath!, usedEncoding: &encoding)
+            XCTAssertEqual(str, "swift-corelibs-foundation")
+            XCTAssertEqual(encoding, String.Encoding.utf8.rawValue, "Wrong encoding detected from UTF8 file")
+        } catch {
+            XCTFail("Unable to init NSString from contentsOfFile:encoding:")
+        }
+    }
+
     func test_FromContentsOfURLUsedEncodingUTF16BE() {
       guard let testFileURL = testBundle().url(forResource: "NSString-UTF16-BE-data", withExtension: "txt") else {
         XCTFail("URL for NSString-UTF16-BE-data.txt is nil")
@@ -1070,34 +1097,6 @@
         }
     }
     
-    //[SR-1988] Ranges of String.UTF16View.Index have negative count
-    func test_StringUTF16ViewIndexStrideableRange(){
-        let testStrings = ["", "\u{0000}", "a", "aa", "ab", "\u{007f}", "\u{0430}", "\u{0430}\u{0431}\u{0432}","\u{1f425}"]
-        
-        func checkStrideable<S : Strideable>(
-            instances: [S],
-            distances: [S.Stride],
-            distanceOracle: (Int, Int) -> S.Stride
-            ) {
-            for i in instances.indices {
-                let first = instances[i]
-                for j in instances.indices {
-                    let second = instances[j]
-                    XCTAssertTrue(distanceOracle(i, j) == first.distance(to: second))
-                    XCTAssertTrue(second == first.advanced(by: distanceOracle(i, j)))
-                }
-            }
-        }
-        testStrings.forEach{
-            let utf16 = $0.utf16
-            var indicies = Array(utf16.indices)
-            indicies.append(utf16.indices.endIndex)
-            checkStrideable(instances: indicies,
-                            distances: Array(0..<utf16.count),
-                       distanceOracle: {$1 - $0})
-        }
-    }
-    
     func test_mutableStringConstructor() {
         let mutableString = NSMutableString(string: "Test")
         XCTAssertEqual(mutableString, "Test")
@@ -1327,11 +1326,11 @@
     // To determine the expected results, compare grapheme clusters,
     // scalar-to-scalar, of the NFD form of the strings.
     let lhsNFDGraphemeClusters =
-        lhs.decomposedStringWithCanonicalMapping.characters.map {
+        lhs.decomposedStringWithCanonicalMapping.map {
             Array(String($0).unicodeScalars)
     }
     let rhsNFDGraphemeClusters =
-        rhs.decomposedStringWithCanonicalMapping.characters.map {
+        rhs.decomposedStringWithCanonicalMapping.map {
             Array(String($0).unicodeScalars)
     }
     let expectHasPrefix = lhsNFDGraphemeClusters.starts(
diff --git a/TestFoundation/TestNSTextCheckingResult.swift b/TestFoundation/TestNSTextCheckingResult.swift
index c74fa09..181898f 100644
--- a/TestFoundation/TestNSTextCheckingResult.swift
+++ b/TestFoundation/TestNSTextCheckingResult.swift
@@ -30,21 +30,21 @@
            let patternOptions: NSRegularExpression.Options = []
            let regex = try NSRegularExpression(pattern: patternString, options: patternOptions)
            let searchString = "1x030cy"
-           let searchOptions: NSMatchingOptions = []
+           let searchOptions: NSRegularExpression.MatchingOptions = []
            let searchRange = NSMakeRange(0,7)
            let match: NSTextCheckingResult =  regex.firstMatch(in: searchString, options: searchOptions, range: searchRange)!
            //Positive offset
-           var result = match.resultByAdjustingRangesWithOffset(1)
+           var result = match.adjustingRanges(offset: 1)
            XCTAssertEqual(result.range(at: 0).location, 6)
            XCTAssertEqual(result.range(at: 1).location, NSNotFound)
            XCTAssertEqual(result.range(at: 2).location, 6)
            //Negative offset
-           result = match.resultByAdjustingRangesWithOffset(-2)
+           result = match.adjustingRanges(offset: -2)
            XCTAssertEqual(result.range(at: 0).location, 3)
            XCTAssertEqual(result.range(at: 1).location, NSNotFound)
            XCTAssertEqual(result.range(at: 2).location, 3)
            //ZeroOffset
-           result = match.resultByAdjustingRangesWithOffset(0)
+           result = match.adjustingRanges(offset: 0)
            XCTAssertEqual(result.range(at: 0).location, 5)
            XCTAssertEqual(result.range(at: 1).location, NSNotFound)
            XCTAssertEqual(result.range(at: 2).location, 5)
diff --git a/TestFoundation/TestNumberFormatter.swift b/TestFoundation/TestNumberFormatter.swift
index 6cf2be6..02914ad 100644
--- a/TestFoundation/TestNumberFormatter.swift
+++ b/TestFoundation/TestNumberFormatter.swift
@@ -14,7 +14,6 @@
     import SwiftFoundation
     import SwiftXCTest
 #endif
-import CoreFoundation
 
 class TestNumberFormatter: XCTestCase {
 
diff --git a/TestFoundation/TestOperationQueue.swift b/TestFoundation/TestOperationQueue.swift
index f60f17b..1dd8c50 100644
--- a/TestFoundation/TestOperationQueue.swift
+++ b/TestFoundation/TestOperationQueue.swift
@@ -28,6 +28,7 @@
             ("test_MainQueueGetter", test_MainQueueGetter),
             ("test_CurrentQueueOnMainQueue", test_CurrentQueueOnMainQueue),
             ("test_CurrentQueueOnBackgroundQueue", test_CurrentQueueOnBackgroundQueue),
+            ("test_CurrentQueueOnBackgroundQueueWithSelfCancel", test_CurrentQueueOnBackgroundQueueWithSelfCancel),
             ("test_CurrentQueueWithCustomUnderlyingQueue", test_CurrentQueueWithCustomUnderlyingQueue),
             ("test_CurrentQueueWithUnderlyingQueueResetToNil", test_CurrentQueueWithUnderlyingQueueResetToNil),
         ]
@@ -135,6 +136,20 @@
         waitForExpectations(timeout: 1)
     }
     
+    func test_CurrentQueueOnBackgroundQueueWithSelfCancel() {
+        let operationQueue = OperationQueue()
+        operationQueue.maxConcurrentOperationCount = 1
+        let expectation = self.expectation(description: "Background execution")
+        operationQueue.addOperation {
+            XCTAssertEqual(operationQueue, OperationQueue.current)
+            expectation.fulfill()
+            // Canceling operation X from inside operation X should not cause the app to a crash
+            operationQueue.cancelAllOperations()
+        }
+        
+        waitForExpectations(timeout: 1)
+    }
+
     func test_CurrentQueueWithCustomUnderlyingQueue() {
         let expectation = self.expectation(description: "Background execution")
         
@@ -175,12 +190,17 @@
 
     override internal(set) var isExecuting: Bool {
         get {
-            return _executing
+            lock.lock()
+            let wasExecuting = _executing
+            lock.unlock()
+            return wasExecuting
         }
         set {
-            if _executing != newValue {
+            if isExecuting != newValue {
                 willChangeValue(forKey: "isExecuting")
+                lock.lock()
                 _executing = newValue
+                lock.unlock()
                 didChangeValue(forKey: "isExecuting")
             }
         }
@@ -188,12 +208,17 @@
 
     override internal(set) var isFinished: Bool {
         get {
-            return _finished
+            lock.lock()
+            let wasFinished = _finished
+            lock.unlock()
+            return wasFinished
         }
         set {
-            if _finished != newValue {
+            if isFinished != newValue {
                 willChangeValue(forKey: "isFinished")
+                lock.lock()
                 _finished = newValue
+                lock.unlock()
                 didChangeValue(forKey: "isFinished")
             }
         }
@@ -213,10 +238,8 @@
 
         queue.async {
             sleep(1)
-            self.lock.lock()
             self.isExecuting = false
             self.isFinished = true
-            self.lock.unlock()
         }
     }
 
diff --git a/TestFoundation/TestPipe.swift b/TestFoundation/TestPipe.swift
index e73405e..29f346b 100644
--- a/TestFoundation/TestPipe.swift
+++ b/TestFoundation/TestPipe.swift
@@ -35,7 +35,7 @@
         aPipe.fileHandleForWriting.write(stringAsData!)
         
         // Then read it out again
-        let data = aPipe.fileHandleForReading.readData(ofLength: text.characters.count)
+        let data = aPipe.fileHandleForReading.readData(ofLength: text.count)
         
         // Confirm that we did read data
         XCTAssertNotNil(data)
diff --git a/TestFoundation/TestProcess.swift b/TestFoundation/TestProcess.swift
index 163dc31..d19340b 100644
--- a/TestFoundation/TestProcess.swift
+++ b/TestFoundation/TestProcess.swift
@@ -14,7 +14,6 @@
     import SwiftFoundation
     import SwiftXCTest
 #endif
-import CoreFoundation
 
 class TestProcess : XCTestCase {
     static var allTests: [(String, (TestProcess) -> () throws -> Void)] {
@@ -29,13 +28,11 @@
                    ("test_pipe_stdout", test_pipe_stdout),
                    ("test_pipe_stderr", test_pipe_stderr),
                    ("test_current_working_directory", test_current_working_directory),
-                   // disabled for now
-                   // ("test_pipe_stdout_and_stderr_same_pipe", test_pipe_stdout_and_stderr_same_pipe),
+                   ("test_pipe_stdout_and_stderr_same_pipe", test_pipe_stdout_and_stderr_same_pipe),
                    ("test_file_stdout", test_file_stdout),
-                   // disabled for now
-                   // ("test_passthrough_environment", test_passthrough_environment),
-                   // ("test_no_environment", test_no_environment),
-                   // ("test_custom_environment", test_custom_environment),
+                   ("test_passthrough_environment", test_passthrough_environment),
+                   ("test_no_environment", test_no_environment),
+                   ("test_custom_environment", test_custom_environment),
         ]
     }
     
@@ -184,7 +181,7 @@
             XCTFail("Could not read stdout")
             return
         }
-        // testing the return value of an external process is does not port well, and may change.
+        // testing the return value of an external process does not port well, and may change.
         // XCTAssertEqual(string, "/bin/cat: invalid_file_name: No such file or directory\n")
     }
 
@@ -198,6 +195,9 @@
         process.standardOutput = pipe
         process.standardError = pipe
 
+        // Clear the environment to stop the malloc debug flags used in Xcode debug being
+        // set in the subprocess.
+        process.environment = [:]
         process.launch()
         process.waitUntilExit()
         XCTAssertEqual(process.terminationStatus, 1)
@@ -207,7 +207,12 @@
             XCTFail("Could not read stdout")
             return
         }
-        XCTAssertEqual(string, "/bin/cat: invalid_file_name: No such file or directory\n")
+
+        // Remove the leading '/bin/' since on macOS '/bin/cat' just outputs 'cat:'
+        let searchStr = "/bin/"
+        let errMsg = string.replacingOccurrences(of: searchStr, with: "", options: [.literal, .anchored],
+                                              range: searchStr.startIndex..<searchStr.endIndex)
+        XCTAssertEqual(errMsg, "cat: invalid_file_name: No such file or directory\n")
     }
 
     func test_file_stdout() {
@@ -235,7 +240,7 @@
     
     func test_passthrough_environment() {
         do {
-            let output = try runTask(["/usr/bin/env"], environment: nil)
+            let (output, _) = try runTask(["/usr/bin/env"], environment: nil)
             let env = try parseEnv(output)
             XCTAssertGreaterThan(env.count, 0)
         } catch let error {
@@ -245,7 +250,7 @@
 
     func test_no_environment() {
         do {
-            let output = try runTask(["/usr/bin/env"], environment: [:])
+            let (output, _) = try runTask(["/usr/bin/env"], environment: [:])
             let env = try parseEnv(output)
             XCTAssertEqual(env.count, 0)
         } catch let error {
@@ -256,7 +261,7 @@
     func test_custom_environment() {
         do {
             let input = ["HELLO": "WORLD", "HOME": "CUPERTINO"]
-            let output = try runTask(["/usr/bin/env"], environment: input)
+            let (output, _) = try runTask(["/usr/bin/env"], environment: input)
             let env = try parseEnv(output)
             XCTAssertEqual(env, input)
         } catch let error {
@@ -268,9 +273,9 @@
         do {
             let previousWorkingDirectory = FileManager.default.currentDirectoryPath
 
-            // `bash` will not be found if the current working directory is not set correctly.
-            let _ = try runTask(["bash", "-c", "exit 0"], currentDirectoryPath: "/bin")
-
+            // Darwin Foundation requires the full path to the executable (.launchPath)
+            let (output, _) = try runTask(["/bin/bash", "-c", "pwd"], currentDirectoryPath: "/bin")
+            XCTAssertEqual(output.trimmingCharacters(in: .newlines), "/bin")
             XCTAssertEqual(previousWorkingDirectory, FileManager.default.currentDirectoryPath)
         } catch let error {
             XCTFail("Test failed: \(error)")
@@ -298,21 +303,26 @@
     case InvalidEnvironmentVariable(String)
 }
 
-private func runTask(_ arguments: [String], environment: [String: String]? = nil, currentDirectoryPath: String? = nil) throws -> String {
+private func runTask(_ arguments: [String], environment: [String: String]? = nil, currentDirectoryPath: String? = nil) throws -> (String, String) {
     let process = Process()
 
     var arguments = arguments
     process.launchPath = arguments.removeFirst()
     process.arguments = arguments
-    process.environment = environment
+    // Darwin Foundation doesnt allow .environment to be set to nil although the documentation
+    // says it is an optional. https://developer.apple.com/documentation/foundation/process/1409412-environment
+    if let e = environment {
+        process.environment = e
+    }
 
     if let directoryPath = currentDirectoryPath {
         process.currentDirectoryPath = directoryPath
     }
 
-    let pipe = Pipe()
-    process.standardOutput = pipe
-    process.standardError = pipe
+    let stdoutPipe = Pipe()
+    let stderrPipe = Pipe()
+    process.standardOutput = stdoutPipe
+    process.standardError = stderrPipe
     process.launch()
     process.waitUntilExit()
 
@@ -320,12 +330,17 @@
         throw Error.TerminationStatus(process.terminationStatus)
     }
 
-    let data = pipe.fileHandleForReading.availableData
-    guard let output = String(data: data, encoding: .utf8) else {
-        throw Error.UnicodeDecodingError(data)
+    let stdoutData = stdoutPipe.fileHandleForReading.availableData
+    guard let stdout = String(data: stdoutData, encoding: .utf8) else {
+        throw Error.UnicodeDecodingError(stdoutData)
     }
 
-    return output
+    let stderrData = stderrPipe.fileHandleForReading.availableData
+    guard let stderr = String(data: stderrData, encoding: .utf8) else {
+        throw Error.UnicodeDecodingError(stderrData)
+    }
+
+    return (stdout, stderr)
 }
 
 private func parseEnv(_ env: String) throws -> [String: String] {
@@ -334,7 +349,7 @@
         guard let range = line.range(of: "=") else {
             throw Error.InvalidEnvironmentVariable(line)
         }
-        result[line.substring(to: range.lowerBound)] = line.substring(from: range.upperBound)
+        result[String(line[..<range.lowerBound])] = String(line[range.upperBound...])
     }
     return result
 }
diff --git a/TestFoundation/TestStream.swift b/TestFoundation/TestStream.swift
index 9517db1..783b5e3 100644
--- a/TestFoundation/TestStream.swift
+++ b/TestFoundation/TestStream.swift
@@ -135,7 +135,7 @@
             XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
             let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
             outputStream?.close()
-            XCTAssertEqual(myString.characters.count, result)
+            XCTAssertEqual(myString.count, result)
             XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
             removeTestFile(filePath!)
         } else {
@@ -154,7 +154,7 @@
         let result: Int? = outputStream.write(encodedData, maxLength: encodedData.count)
         outputStream.close()
         XCTAssertEqual(Stream.Status.closed, outputStream.streamStatus)
-        XCTAssertEqual(myString.characters.count, result)
+        XCTAssertEqual(myString.count, result)
         XCTAssertEqual(NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue), NSString(string: myString))
     }
     
@@ -169,7 +169,7 @@
             XCTAssertEqual(Stream.Status.open, outputStream!.streamStatus)
             let result: Int? = outputStream?.write(encodedData, maxLength: encodedData.count)
             outputStream?.close()
-            XCTAssertEqual(myString.characters.count, result)
+            XCTAssertEqual(myString.count, result)
             XCTAssertEqual(Stream.Status.closed, outputStream!.streamStatus)
             removeTestFile(filePath!)
         } else {
@@ -186,7 +186,7 @@
         outputStream.open()
         XCTAssertEqual(Stream.Status.open, outputStream.streamStatus)
         let result: Int? = outputStream.write(encodedData, maxLength: encodedData.count)
-        XCTAssertEqual(myString.characters.count, result)
+        XCTAssertEqual(myString.count, result)
         //verify the data written
         let dataWritten  = outputStream.property(forKey: Stream.PropertyKey.dataWrittenToMemoryStreamKey)
         if let nsdataWritten = dataWritten as? NSData {
diff --git a/TestFoundation/TestThread.swift b/TestFoundation/TestThread.swift
index 5630059..6098b02 100644
--- a/TestFoundation/TestThread.swift
+++ b/TestFoundation/TestThread.swift
@@ -24,6 +24,9 @@
             ("test_currentThread", test_currentThread ),
             ("test_threadStart", test_threadStart),
             ("test_threadName", test_threadName),
+            ("test_mainThread", test_mainThread),
+            ("test_callStackSymbols", test_callStackSymbols),
+            ("test_callStackReurnAddresses", test_callStackReturnAddresses),
         ]
     }
 
@@ -33,25 +36,23 @@
         XCTAssertNotNil(thread1)
         XCTAssertNotNil(thread2)
         XCTAssertEqual(thread1, thread2)
+        XCTAssertEqual(thread1, Thread.mainThread)
     }
     
     func test_threadStart() {
-        var started = false
         let condition = NSCondition()
+        condition.lock()
+
         let thread = Thread() {
             condition.lock()
-            started = true
             condition.broadcast()
             condition.unlock()
         }
         thread.start()
-        
-        condition.lock()
-        if !started {
-            condition.wait()
-        }
+
+        let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
         condition.unlock()
-        XCTAssertTrue(started)
+        XCTAssertTrue(ok, "NSCondition wait timed out")
     }
     
     func test_threadName() {
@@ -84,4 +85,42 @@
         XCTAssertEqual(thread3.name, "Thread3")
         XCTAssertNotEqual(thread3.name, getPThreadName())
     }
+
+    func test_mainThread() {
+        XCTAssertTrue(Thread.isMainThread)
+        let t = Thread.mainThread
+        XCTAssertTrue(t.isMainThread)
+        let c = Thread.current
+        XCTAssertTrue(c.isMainThread)
+        XCTAssertTrue(c.isExecuting)
+        XCTAssertTrue(c.isEqual(t))
+
+        let condition = NSCondition()
+        condition.lock()
+
+        let thread = Thread() {
+            condition.lock()
+            XCTAssertFalse(Thread.isMainThread)
+            XCTAssertFalse(Thread.mainThread == Thread.current)
+            condition.broadcast()
+            condition.unlock()
+        }
+        thread.start()
+
+        let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
+        condition.unlock()
+        XCTAssertTrue(ok, "NSCondition wait timed out")
+    }
+
+    func test_callStackSymbols() {
+        let symbols = Thread.callStackSymbols
+        XCTAssertTrue(symbols.count > 0)
+        XCTAssertTrue(symbols.count <= 128)
+    }
+
+    func test_callStackReturnAddresses() {
+        let addresses = Thread.callStackReturnAddresses
+        XCTAssertTrue(addresses.count > 0)
+        XCTAssertTrue(addresses.count <= 128)
+    }
 }
diff --git a/TestFoundation/TestURL.swift b/TestFoundation/TestURL.swift
index b0977b1..1ce0bf9 100644
--- a/TestFoundation/TestURL.swift
+++ b/TestFoundation/TestURL.swift
@@ -64,6 +64,7 @@
             ("test_reachable", test_reachable),
             ("test_copy", test_copy),
             ("test_itemNSCoding", test_itemNSCoding),
+            ("test_dataRepresentation", test_dataRepresentation),
         ]
     }
     
@@ -491,6 +492,13 @@
         let queryItemB = NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: queryItemA)) as! NSURLQueryItem
         XCTAssertEqual(queryItemA, queryItemB, "Archived then unarchived query item must be equal.")
     }
+
+    func test_dataRepresentation() {
+        let url = NSURL(fileURLWithPath: "/tmp/foo")
+        let url2 = NSURL(dataRepresentation: url.dataRepresentation,
+            relativeTo: nil)
+        XCTAssertEqual(url, url2)
+    }
 }
     
 class TestURLComponents : XCTestCase {
diff --git a/TestFoundation/TestURLSession.swift b/TestFoundation/TestURLSession.swift
index cf44ab6..c941f1c 100644
--- a/TestFoundation/TestURLSession.swift
+++ b/TestFoundation/TestURLSession.swift
@@ -36,13 +36,14 @@
             ("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
             ("test_timeoutInterval", test_timeoutInterval),
             ("test_httpRedirection", test_httpRedirection),
-            ("test_httpRedirectionTimeout", test_httpRedirectionTimeout),
+            //("test_httpRedirectionTimeout", test_httpRedirectionTimeout), /* temporarily disabled (https://bugs.swift.org/browse/SR-5751) */
             ("test_http0_9SimpleResponses", test_http0_9SimpleResponses),
             ("test_outOfRangeButCorrectlyFormattedHTTPCode", test_outOfRangeButCorrectlyFormattedHTTPCode),
             ("test_missingContentLengthButStillABody", test_missingContentLengthButStillABody),
             ("test_illegalHTTPServerResponses", test_illegalHTTPServerResponses),
             ("test_dataTaskWithSharedDelegate", test_dataTaskWithSharedDelegate),
             ("test_simpleUploadWithDelegate", test_simpleUploadWithDelegate),
+            ("test_concurrentRequests", test_concurrentRequests),
         ]
     }
     
@@ -312,6 +313,8 @@
         waitForExpectations(timeout: 12)
     }
 
+    /*
+     // temporarily disabled (https://bugs.swift.org/browse/SR-5751)
     func test_httpRedirectionTimeout() {
         let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/UnitedStates"
         var req = URLRequest(url: URL(string: urlString)!)
@@ -324,11 +327,14 @@
             if let e = error as? URLError {
                 XCTAssertEqual(e.code, .timedOut, "Unexpected error code")
                 return
+            } else {
+                XCTFail("test unexpectedly succeeded (response=\(response.debugDescription))")
             }
         }
         task.resume()
         waitForExpectations(timeout: 12)
     }
+    */
 
     func test_http0_9SimpleResponses() {
         for brokenCity in ["Pompeii", "Sodom"] {
@@ -459,6 +465,34 @@
         task.resume()
         waitForExpectations(timeout: 20)
     }
+
+    func test_concurrentRequests() {
+        let syncQ = dispatchQueueMake("test_dataTaskWithURL.syncQ")
+        var dataTasks: [DataTask] = []
+        let g = dispatchGroupMake()
+        for f in 0..<640 {
+            g.enter()
+            let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/Nepal"
+            let expectation = self.expectation(description: "GET \(urlString) [\(f)]: with a delegate")
+            globalDispatchQueue.async {
+                let url = URL(string: urlString)!
+                let d = DataTask(with: expectation)
+                d.run(with: url)
+                syncQ.async {
+                    dataTasks.append(d)
+                    g.leave()
+                }
+            }
+        }
+        waitForExpectations(timeout: 12)
+        g.wait()
+        for d in syncQ.sync(execute: {dataTasks}) {
+            if !d.error {
+                XCTAssertEqual(d.capital, "Kathmandu", "test_dataTaskWithURLRequest returned an unexpected result")
+            }
+        }
+    }
+
 }
 
 class SharedDelegate: NSObject {
@@ -488,19 +522,73 @@
 }
 
 class DataTask : NSObject {
+    let syncQ = dispatchQueueMake("org.swift.TestFoundation.TestURLSession.DataTask.syncQ")
     let dataTaskExpectation: XCTestExpectation!
-    var capital = "unknown"
-    var session: URLSession! = nil
-    var task: URLSessionDataTask! = nil
-    var cancelExpectation: XCTestExpectation?
-    var responseReceivedExpectation: XCTestExpectation?
-    var protocols: [AnyClass]?
+    let protocols: [AnyClass]?
+
+    /* all the following var _XYZ need to be synchronized on syncQ.
+       We can't just assert that we're on main thread here as we're modified in the URLSessionDataDelegate extension
+       for DataTask
+     */
+    var _capital = "unknown"
+    var capital: String {
+        get {
+            return self.syncQ.sync { self._capital }
+        }
+        set {
+            self.syncQ.sync { self._capital = newValue }
+        }
+    }
+    var _session: URLSession! = nil
+    var session: URLSession! {
+        get {
+            return self.syncQ.sync { self._session }
+        }
+        set {
+            self.syncQ.sync { self._session = newValue }
+        }
+    }
+    var _task: URLSessionDataTask! = nil
+    var task: URLSessionDataTask! {
+        get {
+            return self.syncQ.sync { self._task }
+        }
+        set {
+            self.syncQ.sync { self._task = newValue }
+        }
+    }
+    var _cancelExpectation: XCTestExpectation?
+    var cancelExpectation: XCTestExpectation? {
+        get {
+            return self.syncQ.sync { self._cancelExpectation }
+        }
+        set {
+            self.syncQ.sync { self._cancelExpectation = newValue }
+        }
+    }
+    var _responseReceivedExpectation: XCTestExpectation?
+    var responseReceivedExpectation: XCTestExpectation? {
+        get {
+            return self.syncQ.sync { self._responseReceivedExpectation }
+        }
+        set {
+            self.syncQ.sync { self._responseReceivedExpectation = newValue }
+        }
+    }
     
-    public var error = false
+    private var _error = false
+    public var error: Bool {
+        get {
+            return self.syncQ.sync { self._error }
+        }
+        set {
+            self.syncQ.sync { self._error = newValue }
+        }
+    }
     
     init(with expectation: XCTestExpectation, protocolClasses: [AnyClass]? = nil) {
         dataTaskExpectation = expectation
-	protocols = protocolClasses
+        protocols = protocolClasses
     }
     
     func run(with request: URLRequest) {
diff --git a/TestFoundation/TestUnit.swift b/TestFoundation/TestUnit.swift
new file mode 100644
index 0000000..c934965
--- /dev/null
+++ b/TestFoundation/TestUnit.swift
@@ -0,0 +1,103 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+    import Foundation
+    import XCTest
+#else
+    import SwiftFoundation
+    import SwiftXCTest
+#endif
+
+class TestUnit: XCTestCase {
+
+    static var allTests: [(String, (TestUnit) -> () throws -> Void)] {
+        return [
+            ("test_equality", test_equality),
+        ]
+    }
+
+    func test_equality() {
+        let s1 = "a"
+        let s2 = "ab"
+
+        let u1 = Unit(symbol: s1)
+        let u2 = Unit(symbol: s1)
+        let u3 = Unit(symbol: s2)
+
+        XCTAssertEqual(u1, u2)
+        XCTAssertEqual(u2, u1)
+        XCTAssertNotEqual(u1, u3)
+        XCTAssertNotEqual(u3, u1)
+
+        let uc1 = UnitConverterLinear(coefficient: 1, constant: 2)
+        let uc2 = UnitConverterLinear(coefficient: 1, constant: 3)
+
+        let d1 = Dimension(symbol: s1, converter: uc1)
+        let d2 = Dimension(symbol: s1, converter: uc1)
+        let d3 = Dimension(symbol: s2, converter: uc1)
+        let d4 = Dimension(symbol: s1, converter: uc2)
+
+        XCTAssertEqual(d1, d2)
+        XCTAssertEqual(d2, d1)
+        XCTAssertNotEqual(d1, d3)
+        XCTAssertNotEqual(d3, d1)
+        XCTAssertNotEqual(d1, d4)
+        XCTAssertNotEqual(d4, d1)
+
+        XCTAssertEqual(u1, d1)
+        XCTAssertNotEqual(d1, u1)
+
+        func testEquality<T: Dimension>(ofDimensionSubclass: T.Type) {
+            let u0 = Unit(symbol: s1)
+            let d1 = Dimension(symbol: s1, converter: uc1)
+
+            let u1 = T(symbol: s1, converter: uc1)
+            let u2 = T(symbol: s1, converter: uc1)
+            let u3 = T(symbol: s1, converter: uc2)
+            let u4 = T(symbol: s2, converter: uc1)
+
+            XCTAssertEqual(u1, u2)
+            XCTAssertEqual(u2, u1)
+            XCTAssertNotEqual(u1, u3)
+            XCTAssertNotEqual(u3, u1)
+            XCTAssertNotEqual(u1, u4)
+            XCTAssertNotEqual(u4, u1)
+
+            XCTAssertEqual(u0, u1)
+            XCTAssertNotEqual(u1, u0)
+
+            XCTAssertEqual(d1, u1)
+            XCTAssertNotEqual(u1, d1)
+        }
+
+        testEquality(ofDimensionSubclass: UnitAcceleration.self)
+        testEquality(ofDimensionSubclass: UnitAngle.self)
+        testEquality(ofDimensionSubclass: UnitArea.self)
+        testEquality(ofDimensionSubclass: UnitConcentrationMass.self)
+        testEquality(ofDimensionSubclass: UnitDispersion.self)
+        testEquality(ofDimensionSubclass: UnitDuration.self)
+        testEquality(ofDimensionSubclass: UnitElectricCharge.self)
+        testEquality(ofDimensionSubclass: UnitElectricCurrent.self)
+        testEquality(ofDimensionSubclass: UnitElectricPotentialDifference.self)
+        testEquality(ofDimensionSubclass: UnitElectricResistance.self)
+        testEquality(ofDimensionSubclass: UnitEnergy.self)
+        testEquality(ofDimensionSubclass: UnitFrequency.self)
+        testEquality(ofDimensionSubclass: UnitFuelEfficiency.self)
+        testEquality(ofDimensionSubclass: UnitIlluminance.self)
+        testEquality(ofDimensionSubclass: UnitLength.self)
+        testEquality(ofDimensionSubclass: UnitMass.self)
+        testEquality(ofDimensionSubclass: UnitPower.self)
+        testEquality(ofDimensionSubclass: UnitPressure.self)
+        testEquality(ofDimensionSubclass: UnitSpeed.self)
+        testEquality(ofDimensionSubclass: UnitTemperature.self)
+        testEquality(ofDimensionSubclass: UnitVolume.self)
+    }
+
+}
diff --git a/TestFoundation/TestUnitConverter.swift b/TestFoundation/TestUnitConverter.swift
index e03e6bb..ed1d374 100644
--- a/TestFoundation/TestUnitConverter.swift
+++ b/TestFoundation/TestUnitConverter.swift
@@ -24,6 +24,7 @@
             ("test_baseUnit", test_linearity),
             ("test_linearity", test_linearity),
             ("test_bijectivity", test_bijectivity),
+            ("test_equality", test_equality),
         ]
     }
     
@@ -267,5 +268,22 @@
         XCTAssertEqual(testIdentity(UnitVolume.imperialGallons), 1, accuracy: delta)
         XCTAssertEqual(testIdentity(UnitVolume.metricCups), 1, accuracy: delta)
     }
+
+    func test_equality() {
+        let u1 = UnitConverterLinear(coefficient: 1, constant: 2)
+        let u2 = UnitConverterLinear(coefficient: 1, constant: 2)
+        XCTAssertEqual(u1, u2)
+        XCTAssertEqual(u2, u1)
+
+        let u3 = UnitConverterLinear(coefficient: 1, constant: 3)
+        XCTAssertNotEqual(u1, u3)
+        XCTAssertNotEqual(u3, u1)
+
+        let u4 = UnitConverterLinear(coefficient: 2, constant: 2)
+        XCTAssertNotEqual(u1, u4)
+        XCTAssertNotEqual(u4, u1)
+
+        // Cannot test UnitConverterReciprocal due to no support for @testable import.
+    }
     
 }
diff --git a/TestFoundation/TestUserDefaults.swift b/TestFoundation/TestUserDefaults.swift
index de01e04..86a2e97 100644
--- a/TestFoundation/TestUserDefaults.swift
+++ b/TestFoundation/TestUserDefaults.swift
@@ -18,9 +18,26 @@
 class TestUserDefaults : XCTestCase {
 	static var allTests : [(String, (TestUserDefaults) -> () throws -> ())] {
 		return [
-			// __kCFXMLPropertyListDomainCallBacks is causing a failure
-			// ("test_createUserDefaults", test_createUserDefaults ),
-			// ("test_getRegisteredDefaultItem", test_getRegisteredDefaultItem ),
+			("test_createUserDefaults", test_createUserDefaults ),
+			("test_getRegisteredDefaultItem", test_getRegisteredDefaultItem ),
+			("test_getRegisteredDefaultItem_NSString", test_getRegisteredDefaultItem_NSString ),
+			("test_getRegisteredDefaultItem_String", test_getRegisteredDefaultItem_String ),
+			("test_getRegisteredDefaultItem_NSURL", test_getRegisteredDefaultItem_NSURL ),
+			("test_getRegisteredDefaultItem_URL", test_getRegisteredDefaultItem_URL ),
+			("test_getRegisteredDefaultItem_NSData", test_getRegisteredDefaultItem_NSData ),
+			("test_getRegisteredDefaultItem_Data)", test_getRegisteredDefaultItem_Data ),
+			("test_getRegisteredDefaultItem_BoolFromString", test_getRegisteredDefaultItem_BoolFromString ),
+			("test_getRegisteredDefaultItem_IntFromString", test_getRegisteredDefaultItem_IntFromString ),
+			("test_getRegisteredDefaultItem_DoubleFromString", test_getRegisteredDefaultItem_DoubleFromString ),
+			("test_setValue_NSString", test_setValue_NSString ),
+			("test_setValue_String", test_setValue_String ),
+			("test_setValue_NSURL", test_setValue_NSURL ),
+			("test_setValue_URL", test_setValue_URL ),
+			("test_setValue_NSData", test_setValue_NSData ),
+			("test_setValue_Data", test_setValue_Data ),
+			("test_setValue_BoolFromString", test_setValue_BoolFromString ),
+			("test_setValue_IntFromString", test_setValue_IntFromString ),
+			("test_setValue_DoubleFromString", test_setValue_DoubleFromString ),
 		]
 	}
 
@@ -40,4 +57,197 @@
 		
 		XCTAssertEqual(defaults.integer(forKey: "key1"), 5)
 	}
+	
+	func test_getRegisteredDefaultItem_NSString() {
+		let defaults = UserDefaults.standard
+		
+		// Register a NSString value. UserDefaults.string(forKey:) is supposed to return the NSString as a String
+		defaults.register(defaults: ["key1": "hello" as NSString])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.string(forKey: "key1"), "hello")
+	}
+
+	func test_getRegisteredDefaultItem_String() {
+		let defaults = UserDefaults.standard
+		
+		// Register a String value. UserDefaults.string(forKey:) is supposed to return the String
+		defaults.register(defaults: ["key1": "hello"])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.string(forKey: "key1"), "hello")
+	}
+
+	func test_getRegisteredDefaultItem_NSURL() {
+		let defaults = UserDefaults.standard
+		
+		// Register an NSURL value. UserDefaults.url(forKey:) is supposed to return the URL
+		defaults.register(defaults: ["key1": NSURL(fileURLWithPath: "/hello/world")])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.url(forKey: "key1"), URL(fileURLWithPath: "/hello/world"))
+	}
+
+	func test_getRegisteredDefaultItem_URL() {
+		let defaults = UserDefaults.standard
+		
+		// Register an URL value. UserDefaults.url(forKey:) is supposed to return the URL
+		defaults.register(defaults: ["key1": URL(fileURLWithPath: "/hello/world")])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.url(forKey: "key1"), URL(fileURLWithPath: "/hello/world"))
+	}
+
+	func test_getRegisteredDefaultItem_NSData() {
+		let defaults = UserDefaults.standard
+		let bytes = [0, 1, 2, 3, 4] as [UInt8]
+		
+		// Register an NSData value. UserDefaults.data(forKey:) is supposed to return the Data
+		defaults.register(defaults: ["key1": NSData(bytes: bytes, length: bytes.count)])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.data(forKey: "key1"), Data(bytes: bytes))
+	}
+	
+	func test_getRegisteredDefaultItem_Data() {
+		let defaults = UserDefaults.standard
+		let bytes = [0, 1, 2, 3, 4] as [UInt8]
+		
+		// Register a Data value. UserDefaults.data(forKey:) is supposed to return the Data
+		defaults.register(defaults: ["key1": Data(bytes: bytes)])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.data(forKey: "key1"), Data(bytes: bytes))
+	}
+
+	func test_getRegisteredDefaultItem_BoolFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register a boolean default value as a string. UserDefaults.bool(forKey:) is supposed to return the parsed Bool value
+		defaults.register(defaults: ["key1": "YES"])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.bool(forKey: "key1"), true)
+	}
+	
+	func test_getRegisteredDefaultItem_IntFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register an int default value as a string. UserDefaults.integer(forKey:) is supposed to return the parsed Int value
+		defaults.register(defaults: ["key1": "1234"])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.integer(forKey: "key1"), 1234)
+	}
+	
+	func test_getRegisteredDefaultItem_DoubleFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register a double default value as a string. UserDefaults.double(forKey:) is supposed to return the parsed Double value
+		defaults.register(defaults: ["key1": "12.34"])
+		
+		//make sure we don't have anything in the saved plist.
+		defaults.removeObject(forKey: "key1")
+		
+		XCTAssertEqual(defaults.double(forKey: "key1"), 12.34)
+	}
+	
+	func test_setValue_NSString() {
+		let defaults = UserDefaults.standard
+		
+		// Set a NSString value. UserDefaults.string(forKey:) is supposed to return the NSString as a String
+		defaults.set("hello" as NSString, forKey: "key1")
+		
+		XCTAssertEqual(defaults.string(forKey: "key1"), "hello")
+	}
+	
+	func test_setValue_String() {
+		let defaults = UserDefaults.standard
+		
+		// Register a String value. UserDefaults.string(forKey:) is supposed to return the String
+		defaults.set("hello", forKey: "key1")
+		
+		XCTAssertEqual(defaults.string(forKey: "key1"), "hello")
+	}
+
+	func test_setValue_NSURL() {
+		let defaults = UserDefaults.standard
+		
+		// Set a NSURL value. UserDefaults.url(forKey:) is supposed to return the NSURL as a URL
+		defaults.set(NSURL(fileURLWithPath: "/hello/world"), forKey: "key1")
+		
+		XCTAssertEqual(defaults.url(forKey: "key1"), URL(fileURLWithPath: "/hello/world"))
+	}
+
+	func test_setValue_URL() {
+		let defaults = UserDefaults.standard
+		
+		// Set a URL value. UserDefaults.url(forKey:) is supposed to return the URL
+		defaults.set(URL(fileURLWithPath: "/hello/world"), forKey: "key1")
+		
+		XCTAssertEqual(defaults.url(forKey: "key1"), URL(fileURLWithPath: "/hello/world"))
+	}
+
+	func test_setValue_NSData() {
+		let defaults = UserDefaults.standard
+		let bytes = [0, 1, 2, 3, 4] as [UInt8]
+		
+		// Set a NSData value. UserDefaults.data(forKey:) is supposed to return the Data
+		defaults.set(NSData(bytes: bytes, length: bytes.count), forKey: "key1")
+		
+		XCTAssertEqual(defaults.data(forKey: "key1"), Data(bytes: bytes))
+	}
+	
+	func test_setValue_Data() {
+		let defaults = UserDefaults.standard
+		let bytes = [0, 1, 2, 3, 4] as [UInt8]
+		
+		// Set a Data value. UserDefaults.data(forKey:) is supposed to return the Data
+		defaults.set(Data(bytes: bytes), forKey: "key1")
+		
+		XCTAssertEqual(defaults.data(forKey: "key1"), Data(bytes: bytes))
+	}
+
+	func test_setValue_BoolFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register a boolean default value as a string. UserDefaults.bool(forKey:) is supposed to return the parsed Bool value
+		defaults.set("YES", forKey: "key1")
+		
+		XCTAssertEqual(defaults.bool(forKey: "key1"), true)
+	}
+	
+	func test_setValue_IntFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register an int default value as a string. UserDefaults.integer(forKey:) is supposed to return the parsed Int value
+		defaults.set("1234", forKey: "key1")
+		
+		XCTAssertEqual(defaults.integer(forKey: "key1"), 1234)
+	}
+	
+	func test_setValue_DoubleFromString() {
+		let defaults = UserDefaults.standard
+		
+		// Register a double default value as a string. UserDefaults.double(forKey:) is supposed to return the parsed Double value
+		defaults.set("12.34", forKey: "key1")
+		
+		XCTAssertEqual(defaults.double(forKey: "key1"), 12.34)
+	}
 }
diff --git a/TestFoundation/TestUtils.swift b/TestFoundation/TestUtils.swift
index b587b36..860e129 100644
--- a/TestFoundation/TestUtils.swift
+++ b/TestFoundation/TestUtils.swift
@@ -41,7 +41,7 @@
                     print(err)
                     return false
                 }
-            } else if !isDir {
+            } else if !isDir.boolValue {
                 return false
             }
             
diff --git a/TestFoundation/TestXMLDocument.swift b/TestFoundation/TestXMLDocument.swift
index d02ef9f..00bbbf4 100644
--- a/TestFoundation/TestXMLDocument.swift
+++ b/TestFoundation/TestXMLDocument.swift
@@ -17,7 +17,6 @@
     import SwiftXCTest
 #endif
 
-import CoreFoundation
 
 class TestXMLDocument : XCTestCase {
 
diff --git a/TestFoundation/TestXMLParser.swift b/TestFoundation/TestXMLParser.swift
index 84e5782..b08f0b3 100644
--- a/TestFoundation/TestXMLParser.swift
+++ b/TestFoundation/TestXMLParser.swift
@@ -86,10 +86,10 @@
             return xmlUnderTest
         }
         if let open = encoding.range(of: "(") {
-            encoding = encoding.substring(from: open.upperBound)
+            encoding = String(encoding[open.upperBound...])
         }
         if let close = encoding.range(of: ")") {
-            encoding = encoding.substring(to: close.lowerBound)
+            encoding = String(encoding[..<close.lowerBound])
         }
         return "<?xml version='1.0' encoding='\(encoding.uppercased())' standalone='no'?>\n\(xmlUnderTest)\n"
     }
diff --git a/TestFoundation/XDGTestHelper.swift b/TestFoundation/XDGTestHelper.swift
index bdf58a0..9692199 100644
--- a/TestFoundation/XDGTestHelper.swift
+++ b/TestFoundation/XDGTestHelper.swift
@@ -35,7 +35,7 @@
         storage.setCookie(simpleCookie!)
         let fm = FileManager.default
         let destPath = xdg_data_home! + "/xdgTestHelper/.cookies.shared"
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: destPath, isDirectory: &isDir) 
         if (!exists) {
             print("Expected cookie path: ", destPath)
diff --git a/TestFoundation/main.swift b/TestFoundation/main.swift
index 6e288ac..a1f6bf9 100644
--- a/TestFoundation/main.swift
+++ b/TestFoundation/main.swift
@@ -10,13 +10,18 @@
 #if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
 import Foundation
 import XCTest
-import Glibc
 #else
 import SwiftFoundation
 import SwiftXCTest
-import Darwin
 #endif
 
+#if os(OSX) || os(iOS)
+    import Darwin
+#elseif os(Linux)
+    import Glibc
+#endif
+
+
 internal func testBundle() -> Bundle {
     return Bundle.main
 }
@@ -58,6 +63,7 @@
     testCase(TestNotificationQueue.allTests),
     testCase(TestNSNull.allTests),
     testCase(TestNSNumber.allTests),
+    testCase(TestNSNumberBridging.allTests),
     testCase(TestNumberFormatter.allTests),
     testCase(TestOperationQueue.allTests),
     testCase(TestNSOrderedSet.allTests),
@@ -73,7 +79,7 @@
     testCase(TestNSSet.allTests),
     testCase(TestStream.allTests),
     testCase(TestNSString.allTests),
-//    testCase(TestThread.allTests),
+    testCase(TestThread.allTests),
     testCase(TestProcess.allTests),
     testCase(TestNSTextCheckingResult.allTests),
     testCase(TestTimer.allTests),
@@ -104,4 +110,5 @@
     testCase(TestMassFormatter.allTests),
     testCase(TestJSONEncoder.allTests),
     testCase(TestCodable.allTests),
+    testCase(TestUnit.allTests),
 ])
diff --git a/build.py b/build.py
index 7cca01a..efe0ce1 100755
--- a/build.py
+++ b/build.py
@@ -15,8 +15,8 @@
 
 swift_cflags = ['-DDEPLOYMENT_RUNTIME_SWIFT']
 if Configuration.current.target.sdk == OSType.Linux:
-	foundation.CFLAGS = '`${PKG_CONFIG} icu-uc icu-i18n --cflags-only-I` -DDEPLOYMENT_TARGET_LINUX -D_GNU_SOURCE -DCF_CHARACTERSET_DATA_DIR="CoreFoundation/CharacterSets"'
-	foundation.LDFLAGS = '${SWIFT_USE_LINKER} -Wl,@./CoreFoundation/linux.ld -lswiftGlibc `${PKG_CONFIG} icu-uc icu-i18n --libs` -Wl,-Bsymbolic '
+	foundation.CFLAGS = '-DDEPLOYMENT_TARGET_LINUX -D_GNU_SOURCE -DCF_CHARACTERSET_DATA_DIR="CoreFoundation/CharacterSets"'
+	foundation.LDFLAGS = '${SWIFT_USE_LINKER} -Wl,@./CoreFoundation/linux.ld -lswiftGlibc -Wl,-Bsymbolic '
 	Configuration.current.requires_pkg_config = True
 elif Configuration.current.target.sdk == OSType.FreeBSD:
 	foundation.CFLAGS = '-DDEPLOYMENT_TARGET_FREEBSD -I/usr/local/include -I/usr/local/include/libxml2 -I/usr/local/include/curl '
@@ -61,35 +61,55 @@
 	'-Wno-unused-variable',
 	'-Wno-int-conversion',
 	'-Wno-unused-function',
-	'-I${SYSROOT}/usr/include/libxml2',
-	'-I${SYSROOT}/usr/include/curl',
 	'-I./',
 ])
 
 swift_cflags += [
 	'-I${BUILD_DIR}/Foundation/usr/lib/swift',
-	'-I${SYSROOT}/usr/include/libxml2',
-	'-I${SYSROOT}/usr/include/curl'
 ]
 
 if "XCTEST_BUILD_DIR" in Configuration.current.variables:
 	swift_cflags += [
 		'-I${XCTEST_BUILD_DIR}',
 		'-L${XCTEST_BUILD_DIR}',
-		'-I${SYSROOT}/usr/include/libxml2',
-		'-I${SYSROOT}/usr/include/curl'
 	]
 
-triple = Configuration.current.target.triple
-if triple.find("linux") != -1:
-	foundation.LDFLAGS += '-lcurl '
+if Configuration.current.requires_pkg_config:
+    pkg_config_dependencies = [
+        'icu-i18n',
+        'icu-uc',
+        'libcurl',
+        'libxml-2.0',
+    ]
+    for package_name in pkg_config_dependencies:
+        try:
+            package = PkgConfig(package_name)
+        except PkgConfig.Error as e:
+            sys.exit("pkg-config error for package {}: {}".format(package_name, e))
+        foundation.CFLAGS += ' {} '.format(' '.join(package.cflags))
+        foundation.LDFLAGS += ' {} '.format(' '.join(package.ldflags))
+        swift_cflags += package.swiftc_flags
+else:
+	foundation.CFLAGS += ''.join([
+		'-I${SYSROOT}/usr/include/curl ',
+		'-I${SYSROOT}/usr/include/libxml2 ',
+	])
+	foundation.LDFLAGS += ''.join([
+		'-lcurl ',
+		'-lxml2 ',
+	])
+	swift_cflags += ''.join([
+		'-I${SYSROOT}/usr/include/curl ',
+		'-I${SYSROOT}/usr/include/libxml2 ',
+	])
 
+triple = Configuration.current.target.triple
 if triple == "armv7-none-linux-androideabi":
 	foundation.LDFLAGS += '-llog '
 else:
 	foundation.LDFLAGS += '-lpthread '
 
-foundation.LDFLAGS += '-ldl -lm -lswiftCore -lxml2 '
+foundation.LDFLAGS += '-ldl -lm -lswiftCore '
 
 # Configure use of Dispatch in CoreFoundation and Foundation if libdispatch is being built
 if "LIBDISPATCH_SOURCE_DIR" in Configuration.current.variables:
@@ -262,6 +282,7 @@
 	'CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c',
 	'CoreFoundation/Preferences.subproj/CFApplicationPreferences.c',
 	'CoreFoundation/Preferences.subproj/CFPreferences.c',
+    'CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c',
 	# 'CoreFoundation/RunLoop.subproj/CFMachPort.c',
 	# 'CoreFoundation/RunLoop.subproj/CFMessagePort.c',
 	'CoreFoundation/RunLoop.subproj/CFRunLoop.c',
diff --git a/configure b/configure
index 4e0f128..f4cc022 100755
--- a/configure
+++ b/configure
@@ -32,6 +32,8 @@
 from lib.product import Application
 from lib.product import Executable
 
+from lib.pkg_config import PkgConfig
+
 from lib.script import Script
 
 from lib.target import ArchSubType
diff --git a/lib/__init__.py b/lib/__init__.py
index 158123d..b55f8a5 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -11,8 +11,9 @@
     "config",
     "path",
     "phases",
+    "pkg_config",
     "product",
     "script",
     "target",
     "workspace",
-]
\ No newline at end of file
+]
diff --git a/lib/pkg_config.py b/lib/pkg_config.py
new file mode 100644
index 0000000..e511075
--- /dev/null
+++ b/lib/pkg_config.py
@@ -0,0 +1,65 @@
+from __future__ import print_function
+
+import shlex
+import subprocess
+import sys
+
+from .config import Configuration
+
+
+class PkgConfig(object):
+    class Error(Exception):
+        """Raised when information could not be obtained from pkg-config."""
+
+    def __init__(self, package_name):
+        """Query pkg-config for information about a package.
+
+        :type package_name: str
+        :param package_name: The name of the package to query.
+        :raises PkgConfig.Error: When a call to pkg-config fails.
+        """
+        self.package_name = package_name
+        self._cflags = self._call("--cflags")
+        self._cflags_only_I = self._call("--cflags-only-I")
+        self._cflags_only_other = self._call("--cflags-only-other")
+        self._libs = self._call("--libs")
+        self._libs_only_l = self._call("--libs-only-l")
+        self._libs_only_L = self._call("--libs-only-L")
+        self._libs_only_other = self._call("--libs-only-other")
+
+    def _call(self, *pkg_config_args):
+        try:
+            cmd = [Configuration.current.pkg_config] + list(pkg_config_args) + [self.package_name]
+            print("Executing command '{}'".format(cmd), file=sys.stderr)
+            return shlex.split(subprocess.check_output(cmd))
+        except subprocess.CalledProcessError as e:
+            raise self.Error("pkg-config exited with error code {}".format(e.returncode))
+
+    @property
+    def swiftc_flags(self):
+        """Flags for this package in a format suitable for passing to `swiftc`.
+
+        :rtype: list[str]
+        """
+        return (
+                ["-Xcc {}".format(s) for s in self._cflags_only_other]
+                + ["-Xlinker {}".format(s) for s in self._libs_only_other]
+                + self._cflags_only_I
+                + self._libs_only_L
+                + self._libs_only_l)
+
+    @property
+    def cflags(self):
+        """CFLAGS for this package.
+
+        :rtype: list[str]
+        """
+        return self._cflags
+
+    @property
+    def ldflags(self):
+        """LDFLAGS for this package.
+
+        :rtype: list[str]
+        """
+        return self._libs