Merge pull request #1160 from bubski/cg-api

diff --git a/.gitignore b/.gitignore
index f050b65..6b4d18e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*~
+
 # Mac OS X filesystem metadata
 .DS_Store
 
diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c
index 896193f..70597d1 100644
--- a/CoreFoundation/Base.subproj/CFPlatform.c
+++ b/CoreFoundation/Base.subproj/CFPlatform.c
@@ -1327,6 +1327,7 @@
 CF_SWIFT_EXPORT int _CFThreadGetName(char *buf, int length) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return pthread_getname_np(pthread_self(), buf, length);
+#elif DEPLOYMENT_TARGET_ANDROID
 #elif DEPLOYMENT_TARGET_LINUX
     return pthread_getname_np(pthread_self(), buf, length);
 #endif
diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c
index d536d46..aa40131 100644
--- a/CoreFoundation/Base.subproj/CFUtilities.c
+++ b/CoreFoundation/Base.subproj/CFUtilities.c
@@ -1519,7 +1519,7 @@
     static CFMutableDictionaryRef envDict = NULL;
     dispatch_once(&once, ^{
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-        extern char ***_NSGetEnviron();
+        extern char ***_NSGetEnviron(void);
         char **envp = *_NSGetEnviron();
 #elif DEPLOYMENT_TARGET_FREEBSD || TARGET_OS_CYGWIN
         extern char **environ;
diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
index 2d20856..2651cd8 100644
--- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
+++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
@@ -27,10 +27,9 @@
 #include <CoreFoundation/ForFoundationOnly.h>
 #include <fts.h>
 #include <pthread.h>
-#include <execinfo.h>
 
-#if __has_include(<malloc/malloc.h>)
-#include <malloc/malloc.h>
+#if __has_include(<execinfo.h>)
+#include <execinfo.h>
 #endif
 
 #if __has_include(<malloc/malloc.h>)
diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter.c b/CoreFoundation/Locale.subproj/CFDateFormatter.c
index 8465c34..48ef1e2 100644
--- a/CoreFoundation/Locale.subproj/CFDateFormatter.c
+++ b/CoreFoundation/Locale.subproj/CFDateFormatter.c
@@ -66,7 +66,7 @@
         if (CFStringGetCString(ln, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) localeName = buffer;
     }
     
-    static void (^flushCache)() = ^{
+    static void (^flushCache)(void) = ^{
         __cficu_udatpg_close(ptg);
         ptg = NULL;
         free((void *)ptgLocaleName);
@@ -1506,7 +1506,7 @@
         }
     } else {
         if (period < INT_MAX && futureMax > period) {
-            futureRange.location = 1,
+            futureRange.location = 1;
             futureRange.length = futureMax - period;
         }
         if (pastMin <= 0) {
diff --git a/CoreFoundation/RunLoop.subproj/CFRunLoop.c b/CoreFoundation/RunLoop.subproj/CFRunLoop.c
index b92c2bf..02cc72d 100644
--- a/CoreFoundation/RunLoop.subproj/CFRunLoop.c
+++ b/CoreFoundation/RunLoop.subproj/CFRunLoop.c
@@ -250,8 +250,7 @@
 
 static uint32_t __CF_last_warned_port_count = 0;
 
-static void foo() __attribute__((unused));
-static void foo() {
+static void __attribute__((unused)) foo() {
     uint32_t pcnt = __CFGetProcessPortCount();
     if (__CF_last_warned_port_count + 1000 < pcnt) {
         CFArrayRef threads = __CFStopAllThreads();
@@ -1755,32 +1754,28 @@
 
 #if __HAS_DISPATCH__
 
-static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) {
+static void __attribute__((noinline)) __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) {
     _dispatch_main_queue_callback_4CF(msg);
     asm __volatile__(""); // thwart tail-call optimization
 }
 
 #endif
 
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
+static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
     if (func) {
         func(observer, activity, info);
     }
     asm __volatile__(""); // thwart tail-call optimization
 }
 
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(CFRunLoopTimerCallBack func, CFRunLoopTimerRef timer, void *info) {
+static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(CFRunLoopTimerCallBack func, CFRunLoopTimerRef timer, void *info) {
     if (func) {
         func(timer, info);
     }
     asm __volatile__(""); // thwart tail-call optimization
 }
 
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(void (^block)(void)) {
+static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(void (^block)(void)) {
     if (block) {
         block();
     }
@@ -1836,8 +1831,7 @@
 }
 
 /* rl is locked, rlm is locked on entrance and exit */
-static void __CFRunLoopDoObservers() __attribute__((noinline));
-static void __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopActivity activity) {	/* DOES CALLOUT */
+static void __attribute__((noinline)) __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopActivity activity) {	/* DOES CALLOUT */
     CHECK_FOR_FORK();
 
     CFIndex cnt = rlm->_observers ? CFArrayGetCount(rlm->_observers) : 0;
@@ -1904,16 +1898,14 @@
     }
 }
 
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(void (*perform)(void *), void *info) {
+static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(void (*perform)(void *), void *info)  {
     if (perform) {
         perform(info);
     }
     asm __volatile__(""); // thwart tail-call optimization
 }
 
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() __attribute__((noinline));
-static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(
+static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         void *(*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info),
         mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply,
@@ -1997,8 +1989,7 @@
 }
 
 // msg, size and reply are unused on Windows
-static Boolean __CFRunLoopDoSource1() __attribute__((noinline));
-static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls
+static Boolean __attribute__((noinline)) __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                                     , mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply
 #endif
diff --git a/CoreFoundation/String.subproj/CFString.c b/CoreFoundation/String.subproj/CFString.c
index d9ab9ac..ad8e930 100644
--- a/CoreFoundation/String.subproj/CFString.c
+++ b/CoreFoundation/String.subproj/CFString.c
@@ -3233,7 +3233,7 @@
 
                                     do {
                                         str1Char = CFStringGetCharacterFromInlineBuffer(&inlineBuf1, --index);
-                                    } while (CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP), (rangeToSearch.location < index));
+                                    } while (CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP) && (rangeToSearch.location < index));
 
                                     if (str1Char < 0x0510) {
                                         while (++str1Index < maxStr1Index) if (!CFUniCharIsMemberOfBitmap(CFStringGetCharacterFromInlineBuffer(&inlineBuf1, str1Index), graphemeBMP)) break;
diff --git a/CoreFoundation/URL.subproj/CFURL.c b/CoreFoundation/URL.subproj/CFURL.c
index 191e713..13e40d9 100644
--- a/CoreFoundation/URL.subproj/CFURL.c
+++ b/CoreFoundation/URL.subproj/CFURL.c
@@ -28,8 +28,10 @@
 #if __has_include(<sys/syslog.h>)
 #include <sys/syslog.h>
 #else
+#if !TARGET_OS_ANDROID
 #include <syslog.h>
 #endif
+#endif
 #include <CoreFoundation/CFURLPriv.h>
 #endif
 
diff --git a/CoreFoundation/URL.subproj/CFURLSessionInterface.c b/CoreFoundation/URL.subproj/CFURLSessionInterface.c
index f44f44d..887b4f2 100644
--- a/CoreFoundation/URL.subproj/CFURLSessionInterface.c
+++ b/CoreFoundation/URL.subproj/CFURLSessionInterface.c
@@ -19,6 +19,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CFURLSessionInterface.h"
+#include <CoreFoundation/CFString.h>
 #include <curl/curl.h>
 
 FILE* aa = NULL;
@@ -31,6 +32,11 @@
     return (CFURLSessionMultiCode) { value };
 }
 
+CFStringRef CFURLSessionCreateErrorDescription(int value) {
+    const char *description = curl_easy_strerror(value);
+    return CFStringCreateWithBytes(kCFAllocatorSystemDefault,
+        (const uint8_t *)description, strlen(description), kCFStringEncodingUTF8, NO);
+}
 
 CFURLSessionEasyHandle _Nonnull CFURLSessionEasyHandleInit() {
     return curl_easy_init();
@@ -135,6 +141,7 @@
     return MakeEasyCode(curl_global_init(CURL_GLOBAL_SSL));
 }
 
+int const CFURLSessionEasyErrorSize = { CURL_ERROR_SIZE + 1 };
 
 CFURLSessionEasyCode const CFURLSessionEasyCodeOK = { CURLE_OK };
 CFURLSessionEasyCode const CFURLSessionEasyCodeUNSUPPORTED_PROTOCOL = { CURLE_UNSUPPORTED_PROTOCOL };
diff --git a/CoreFoundation/URL.subproj/CFURLSessionInterface.h b/CoreFoundation/URL.subproj/CFURLSessionInterface.h
index 6dc29bc..131b576 100644
--- a/CoreFoundation/URL.subproj/CFURLSessionInterface.h
+++ b/CoreFoundation/URL.subproj/CFURLSessionInterface.h
@@ -48,6 +48,10 @@
     int value;
 } CFURLSessionEasyCode;
 
+CF_EXPORT CFStringRef _Nonnull CFURLSessionCreateErrorDescription(int value);
+
+CF_EXPORT int const CFURLSessionEasyErrorSize;
+
 /// CURLcode
 CF_EXPORT CFURLSessionEasyCode const CFURLSessionEasyCodeOK; // CURLE_OK
 CF_EXPORT CFURLSessionEasyCode const CFURLSessionEasyCodeUNSUPPORTED_PROTOCOL; // CURLE_UNSUPPORTED_PROTOCOL
diff --git a/Docs/Status.md b/Docs/Status.md
index fa06c03..7a58b1d 100644
--- a/Docs/Status.md
+++ b/Docs/Status.md
@@ -47,7 +47,7 @@
     |------------------------------|-----------------|---------------|--------------------------------------------------------------------------------------------------------------------|
     | `URLAuthenticationChallenge` | Unimplemented   | None          |                                                                                                                    |
     | `URLCache`                   | Unimplemented   | None          |                                                                                                                    |
-    | `URLCredential`              | Complete | Incomplete    | 									                                                                                  |
+    | `URLCredential`              | Complete        | Incomplete    |                                                                                                                    |
     | `URLCredentialStorage`       | Unimplemented   | None          |                                                                                                                    |
     | `NSURLError*`                | Complete        | N/A           |                                                                                                                    |
     | `URLProtectionSpace`         | Unimplemented   | None          |                                                                                                                    |
@@ -96,13 +96,13 @@
     | `DateComponentFormatter`        | Unimplemented   | None          |                                                                                           |
     | `DateIntervalFormatter`         | Unimplemented   | None          |                                                                                           |
     | `EnergyFormatter`               | Unimplemented   | None          |                                                                                           |
-    | `ISO8601DateFormatter`        | Unimplemented   | None          |                                                                                           |
-    | `LengthFormatter`               | Complete 	    | Substantial   |                                                                                           |
+    | `ISO8601DateFormatter`          | Unimplemented   | None          |                                                                                           |
+    | `LengthFormatter`               | Complete        | Substantial   |                                                                                           |
     | `MassFormatter`                 | Complete        | Substantial   | Needs localization                                                                        |
     | `NumberFormatter`               | Mostly Complete | Substantial   | `objectValue(_:range:)` remains unimplemented                                             |
     | `PersonNameComponentsFormatter` | Unimplemented   | None          |                                                                                           |
     | `ByteCountFormatter`            | Mostly Complete | Substantial   | `init?(coder:)` remains unimplemented                                                     |
-    | `DateFormatter`                 | Mostly Complete | Incomplete    | `objectValue(_:range:)` remain unimplemented 										 |
+    | `DateFormatter`                 | Mostly Complete | Incomplete    | `objectValue(_:range:)` remain unimplemented                                              |
     | `Formatter`                     | Complete        | N/A           |                                                                                           |
     | `MeasurementFormatter`          | Unimplemented   | None          |                                                                                           |
 
@@ -123,8 +123,8 @@
 
     | Entity Name                 | Status          | Test Coverage | Notes                                                                         |
     |-----------------------------|-----------------|---------------|-------------------------------------------------------------------------------|
-    | `NSJSONSerialization`       | Mostly Complete | Substantial   | `jsonObject(with:options:)` with streams remains unimplemented             |
-    | `NSKeyedArchiver`           | Complete        | Substantial   |                              |
+    | `NSJSONSerialization`       | Mostly Complete | Substantial   | `jsonObject(with:options:)` with streams remains unimplemented                |
+    | `NSKeyedArchiver`           | Complete        | Substantial   |                                                                               |
     | `NSKeyedCoderOldStyleArray` | N/A             | N/A           | For internal use only                                                         |
     | `NSKeyedUnarchiver`         | Mostly Complete | Substantial   | `decodingFailurePolicy.set` remains unimplemented                             |
     | `NSKeyedArchiverHelpers`    | N/A             | N/A           | For internal use only                                                         |
@@ -152,7 +152,7 @@
 
     | Entity Name           | Status          | Test Coverage | Notes                                                                                                                                                               |
     |-----------------------|-----------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-    | `NSOrderedSet`        | Mostly Complete | Substantial   | `NS[Mutable]Copying`, and `array` & `set` (and associated indexing methods) remain unimplemented                        |
+    | `NSOrderedSet`        | Mostly Complete | Substantial   | `NS[Mutable]Copying`, and `array` & `set` (and associated indexing methods) remain unimplemented                                                                    |
     | `NSMutableOrderedSet` | Mostly Complete | Substantial   | `NSCoding` and `sortRange(_:options:, usingComparator:)` with non-empty options remain unimplemented                                                                |
     | `NSCFArray`           | N/A             | N/A           | For internal use only                                                                                                                                               |
     | `NSIndexSet`          | Mostly Complete | Incomplete    | `NSCoding`, `NSCopying`, and concurrent `enumerateWithOptions(_:range:paramType:returnType:block:)` remain unimplemented                                            |
@@ -197,10 +197,10 @@
 
     | Entity Name                 | Status          | Test Coverage | Notes                                                                                                                                                            |
     |-----------------------------|-----------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-    | `NSRegularExpression`       | Complete        | Substantial   |                                                                                                                                 |
+    | `NSRegularExpression`       | Complete        | Substantial   |                                                                                                                                                                  |
     | `Scanner`                   | Mostly Complete | Incomplete    | `scanHex<T: _FloatLike>(_:locale:locationToScanFrom:to:)` and `localizedScannerWithString(_:)` remain unimplemented                                              |
     | `NSTextCheckingResult`      | Mostly Complete | Incomplete    | `NSCoding`, `NSCopying`, `resultType`, and `range(at:)` remain unimplemented                                                                                     |
-    | `NSAttributedString`        | Incomplete      | Incomplete    | `NSCoding`, `NS[Mutable]Copying`, `attributedSubstring(from:)`, `isEqual(to:)`, `init(NSAttributedString:)` remain unimplemented |
+    | `NSAttributedString`        | Incomplete      | Incomplete    | `NSCoding`, `NS[Mutable]Copying`, `attributedSubstring(from:)`, `isEqual(to:)`, `init(NSAttributedString:)` remain unimplemented                                 |
     | `NSMutableAttributedString` | Unimplemented   | Incomplete    | Only `addAttribute(_:value:range:)` is implemented                                                                                                               |
     | `NSCharacterSet`            | Mostly Complete | Incomplete    | `NSCoding` remains unimplemented                                                                                                                                 |
     | `NSMutableCharacterSet`     | Mostly Complete | None          | Decoding remains unimplemented                                                                                                                                   |
@@ -216,14 +216,14 @@
 
     | Entity Name                       | Status          | Test Coverage | Notes                                                                         |
     |-----------------------------------|-----------------|---------------|-------------------------------------------------------------------------------|
-    | `NSRange`                         | Complete 		  | Incomplete    | 															                |
+    | `NSRange`                         | Complete        | Incomplete    |                                                                               |
     | `Decimal`                         | Unimplemented   | None          |                                                                               |
     | `NSDecimalNumber`                 | Unimplemented   | None          |                                                                               |
     | `NSDecimalNumberHandler`          | Unimplemented   | None          |                                                                               |
     | `CGPoint`                         | Complete        | Substantial   |                                                                               |
     | `CGSize`                          | Complete        | Substantial   |                                                                               |
     | `CGRect`                          | Complete        | Substantial   |                                                                               |
-    | `NSEdgeInsets`                    | Mostly Complete | None          | 															                |
+    | `NSEdgeInsets`                    | Mostly Complete | None          |                                                                               |
     | `NSGeometry`                      | Mostly Complete | Substantial   | `NSIntegralRectWithOptions` `.AlignRectFlipped` support remains unimplemented |
     | `CGFloat`                         | Complete        | Substantial   |                                                                               |
     | `AffineTransform`                 | Complete        | None          |                                                                               |
@@ -265,7 +265,7 @@
     | Entity Name    | Statues         | Test Coverage | Notes                                                                                                                         |
     |----------------|-----------------|---------------|-------------------------------------------------------------------------------------------------------------------------------|
     | `UserDefaults` | Incomplete      | None          | `dictionaryRepresentation()`, domain support, and forced objects remain unimplemented. Unit tests are currently commented out |
-    | `NSLocale`     | Complete		   | Incomplete    | Only unit test asserts locale key constant names																             |
+    | `NSLocale`     | Complete        | Incomplete    | Only unit test asserts locale key constant names                                                                              |
     | `Locale`       | Complete        | Incomplete    | Only unit test asserts value copying                                                                                          |
 
 * **OS**: Mechanisms for interacting with the operating system on a file system level as well as process and thread level
@@ -282,24 +282,24 @@
     | `Operation`      | Complete        | Incomplete    |                                                                                                                           |
     | `BlockOperation` | Complete        | Incomplete    |                                                                                                                           |
     | `OperationQueue` | Complete        | Incomplete    |                                                                                                                           |
-    | `Lock`           | Mostly Complete | None          | `lock(before:)` remains unimplemented                                                                                     |
+    | `Lock`           | Complete        | Incomplete    |                                                                                                                           |
     | `ConditionLock`  | Complete        | None          |                                                                                                                           |
-    | `RecursiveLock`  | Mostly Complete | None          | `lock(before:)` remains unimplemented                                                                                     |
-    | `Condition`      | Complete        | None          |                                                                                                                           |
+    | `RecursiveLock`  | Complete        | None          |                                                                                                                           |
+    | `Condition`      | Complete        | Incomplete    |                                                                                                                           |
 
 * **DateTime**: Classes for representing dates, timezones, and calendars.
 
     | Entity Name        | Status          | Test Coverage | Notes                                                                                                                           |
     |--------------------|-----------------|---------------|---------------------------------------------------------------------------------------------------------------------------------|
-    | `NSCalendar`       | Complete		   | None          | `autoupdatingCurrent`, and `enumerateDates` remain unimplemented                    								  |
-    | `NSDateComponents` | Complete		   | None          | 								                                                                     |
+    | `NSCalendar`       | Complete        | None          | `autoupdatingCurrent`, and `enumerateDates` remain unimplemented                                                                |
+    | `NSDateComponents` | Complete        | None          |                                                                                                                                 |
     | `Calendar`         | Complete        | Incomplete    |                                                                                                                                 |
     | `DateComponents`   | Complete        | Incomplete    |                                                                                                                                 |
-    | `NSDate`           | Complete		   | Incomplete    |                                    |
+    | `NSDate`           | Complete        | Incomplete    |                                                                                                                                 |
     | `NSDateInterval`   | Complete        | None          |                                                                                                                                 |
     | `DateInterval`     | Complete        | None          |                                                                                                                                 |
     | `Date`             | Complete        | Incomplete    |                                                                                                                                 |
-    | `NSTimeZone`       | Mostly Complete | Incomplete    | `local`, `timeZoneDataVersion` and setting `abbreviationDictionary` remain unimplemented 					  |
+    | `NSTimeZone`       | Mostly Complete | Incomplete    | `local`, `timeZoneDataVersion` and setting `abbreviationDictionary` remain unimplemented                                        |
     | `TimeZone`         | Complete        | Incomplete    |                                                                                                                                 |
 
 * **Notifications**: Classes for loosely coupling events from a set of many observers.
diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index eeace9e..4fff062 100644
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -326,6 +326,7 @@
 		B910957B1EEF237800A71930 /* NSString-UTF16-BE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */; };
 		B933A79E1F3055F700FE6846 /* NSString-UTF32-BE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */; };
 		B933A79F1F3055F700FE6846 /* NSString-UTF32-LE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B933A79D1F3055F600FE6846 /* NSString-UTF32-LE-data.txt */; };
+		B951B5EC1F4E2A2000D8B332 /* TestNSLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */; };
 		B9974B961EDF4A22007F15B8 /* TransferState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B8F1EDF4A22007F15B8 /* TransferState.swift */; };
 		B9974B971EDF4A22007F15B8 /* MultiHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B901EDF4A22007F15B8 /* MultiHandle.swift */; };
 		B9974B981EDF4A22007F15B8 /* libcurlHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B911EDF4A22007F15B8 /* libcurlHelpers.swift */; };
@@ -795,6 +796,7 @@
 		B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "NSString-UTF16-BE-data.txt"; sourceTree = "<group>"; };
 		B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NSString-UTF32-BE-data.txt"; sourceTree = "<group>"; };
 		B933A79D1F3055F600FE6846 /* NSString-UTF32-LE-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NSString-UTF32-LE-data.txt"; sourceTree = "<group>"; };
+		B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestNSLock.swift; sourceTree = "<group>"; };
 		B9974B8F1EDF4A22007F15B8 /* TransferState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransferState.swift; path = http/TransferState.swift; sourceTree = "<group>"; };
 		B9974B901EDF4A22007F15B8 /* MultiHandle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MultiHandle.swift; path = http/MultiHandle.swift; sourceTree = "<group>"; };
 		B9974B911EDF4A22007F15B8 /* libcurlHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = libcurlHelpers.swift; path = http/libcurlHelpers.swift; sourceTree = "<group>"; };
@@ -1498,6 +1500,7 @@
 				400E22641C1A4E58007C5933 /* TestProcessInfo.swift */,
 				EA01AAEB1DA839C4008F4E07 /* TestProgress.swift */,
 				5E5835F31C20C9B500C81317 /* TestThread.swift */,
+				B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */,
 				CC5249BF1D341D23007CB54D /* TestUnitConverter.swift */,
 				D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
 				5B6F17961C48631C00935030 /* TestUtils.swift */,
@@ -2445,6 +2448,7 @@
 				D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */,
 				D4FE895B1D703D1100DA7986 /* TestURLRequest.swift in Sources */,
 				684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */,
+				B951B5EC1F4E2A2000D8B332 /* TestNSLock.swift in Sources */,
 				5B13B33A1C582D4C00651CE2 /* TestNSNumber.swift in Sources */,
 				5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
 				5B13B3311C582D4C00651CE2 /* TestIndexPath.swift in Sources */,
diff --git a/Foundation/AffineTransform.swift b/Foundation/AffineTransform.swift
index 3f1923f..845c5df 100644
--- a/Foundation/AffineTransform.swift
+++ b/Foundation/AffineTransform.swift
@@ -32,25 +32,20 @@
     public var m22: CGFloat
     public var tX: CGFloat
     public var tY: CGFloat
-    
+
+    /// Creates an affine transformation matrix with identity values.
     public init() {
-        self.init(m11: CGFloat(), m12: CGFloat(), m21: CGFloat(), m22: CGFloat(), tX: CGFloat(), tY: CGFloat())
+        self.init(m11: 1.0, m12: 0.0,
+                  m21: 0.0, m22: 1.0,
+                   tX: 0.0,  tY: 0.0)
     }
+
+    /// Creates an affine transformation.
     public init(m11: CGFloat, m12: CGFloat, m21: CGFloat, m22: CGFloat, tX: CGFloat, tY: CGFloat) {
         (self.m11, self.m12, self.m21, self.m22) = (m11, m12, m21, m22)
         (self.tX, self.tY) = (tX, tY)
     }
 
-    private init(reference: NSAffineTransform) {
-        self = reference.transformStruct
-    }
-
-    private var reference : NSAffineTransform {
-        let ref = NSAffineTransform()
-        ref.transformStruct = self
-        return ref
-    }
-
     /**
      Creates an affine transformation matrix from translation values.
      The matrix takes the following form:
@@ -191,11 +186,12 @@
         )
     }
 
-    // Scaling
+    /// Mutates an affine transformation matrix to perform the given scaling in both x and y dimensions.
     public mutating func scale(_ scale: CGFloat) {
         self.scale(x: scale, y: scale)
     }
 
+    /// Mutates an affine transformation matrix to perform a scaling in each of the x and y dimensions.
     public mutating func scale(x: CGFloat, y: CGFloat) {
         m11 = CGFloat(m11.native * x.native)
         m12 = CGFloat(m12.native * x.native)
@@ -221,6 +217,7 @@
         self = inverse
     }
 
+    /// Returns an inverted version of the matrix if possible, or nil if not.
     public func inverted() -> AffineTransform? {
         let determinant = (m11 * m22) - (m12 * m21)
         if fabs(determinant.native) <= ε.native {
@@ -236,16 +233,17 @@
         return inverse
     }
 
-    // Transforming with transform
+    /// Mutates an affine transformation by appending the specified matrix.
     public mutating func append(_ transform: AffineTransform) {
         self = concatenated(transform)
     }
 
+    /// Mutates an affine transformation by prepending the specified matrix.
     public mutating func prepend(_ transform: AffineTransform) {
         self = transform.concatenated(self)
     }
 
-    // Transforming points and sizes
+    /// Applies the transform to the specified point and returns the result.
     public func transform(_ point: NSPoint) -> NSPoint {
         var newPoint = NSPoint()
         newPoint.x = (m11 * point.x) + (m21 * point.y) + tX
@@ -253,6 +251,7 @@
         return newPoint
     }
 
+    /// Applies the transform to the specified size and returns the result.
     public func transform(_ size: NSSize) -> NSSize {
         var newSize = NSSize()
         newSize.width = (m11 * size.width) + (m21 * size.height)
@@ -260,14 +259,17 @@
         return newSize
     }
 
+    /// The computed hash value for the transform.
     public var hashValue : Int {
         return Int((m11 + m12 + m21 + m22 + tX + tY).native)
     }
 
+    /// A textual description of the transform.
     public var description: String {
         return "{m11:\(m11), m12:\(m12), m21:\(m21), m22:\(m22), tX:\(tX), tY:\(tY)}"
     }
 
+    /// A textual description of the transform suitable for debugging.
     public var debugDescription: String {
         return description
     }
@@ -279,8 +281,61 @@
     }
 }
 
+
+/// A structure that defines the three-by-three matrix that performs an affine transform between two coordinate systems.
+public struct NSAffineTransformStruct {
+    public var m11: CGFloat
+    public var m12: CGFloat
+    public var m21: CGFloat
+    public var m22: CGFloat
+    public var tX: CGFloat
+    public var tY: CGFloat
+
+    /// Initializes a zero-filled transformation matrix.
+    public init() {
+        m11 = 0.0
+        m12 = 0.0
+        m21 = 0.0
+        m22 = 0.0
+        tX = 0.0
+        tY = 0.0
+    }
+
+    /// Initializes a transformation matrix with the given values.
+    public init(m11: CGFloat, m12: CGFloat, m21: CGFloat, m22: CGFloat, tX: CGFloat, tY: CGFloat) {
+        self.m11 = m11
+        self.m12 = m12
+        self.m21 = m21
+        self.m22 = m22
+        self.tX = tX
+        self.tY = tY
+    }
+}
+
 open class NSAffineTransform : NSObject, NSCopying, NSSecureCoding {
-    
+
+    private var affineTransform: AffineTransform
+
+    /// The matrix coefficients stored as the transformation matrix.
+    public var transformStruct: NSAffineTransformStruct {
+        get {
+            return NSAffineTransformStruct(m11: affineTransform.m11,
+                                           m12: affineTransform.m12,
+                                           m21: affineTransform.m21,
+                                           m22: affineTransform.m22,
+                                           tX: affineTransform.tX,
+                                           tY: affineTransform.tY)
+        }
+        set {
+            affineTransform.m11 = newValue.m11
+            affineTransform.m12 = newValue.m12
+            affineTransform.m21 = newValue.m21
+            affineTransform.m22 = newValue.m22
+            affineTransform.tX = newValue.tX
+            affineTransform.tY = newValue.tY
+        }
+    }
+
     open func encode(with aCoder: NSCoder) {
         guard aCoder.allowsKeyedCoding else {
             preconditionFailure("Unkeyed coding is unsupported.")
@@ -301,7 +356,7 @@
     }
     
     open func copy(with zone: NSZone? = nil) -> Any {
-        return NSAffineTransform(transform: self)
+        return NSAffineTransform(transform: affineTransform)
     }
     
     // Necessary because `NSObject.copy()` returns `self`.
@@ -328,94 +383,97 @@
         let tX = floatPointer[4]
         let tY = floatPointer[5]
 
-        self.transformStruct = AffineTransform(m11: CGFloat(m11), m12: CGFloat(m12),
-                                               m21: CGFloat(m21), m22: CGFloat(m22),
-                                               tX: CGFloat(tX), tY: CGFloat(tY))
+        affineTransform = AffineTransform(m11: CGFloat(m11), m12: CGFloat(m12),
+                                          m21: CGFloat(m21), m22: CGFloat(m22),
+                                          tX: CGFloat(tX), tY: CGFloat(tY))
     }
     
     open override func isEqual(_ object: Any?) -> Bool {
         guard let other = object as? NSAffineTransform else { return false }
-        return other === self
-            || (other.transformStruct == self.transformStruct)
+        return other === self || (other.affineTransform == self.affineTransform)
     }
 
     open override var hashValue: Int {
-        return transformStruct.hashValue
+        return affineTransform.hashValue
     }
     
     public static var supportsSecureCoding: Bool {
         return true
     }
     
-    // Initialization
-    public convenience init(transform: NSAffineTransform) {
+    /// Initializes an affine transform matrix using another transform object.
+    public convenience init(transform: AffineTransform) {
         self.init()
-        transformStruct = transform.transformStruct
+        affineTransform = transform
     }
-    
+
+    /// Initializes an affine transform matrix to the identity matrix.
     public override init() {
-        transformStruct = AffineTransform(
+        affineTransform = AffineTransform(
             m11: CGFloat(1.0), m12: CGFloat(),
             m21: CGFloat(), m22: CGFloat(1.0),
             tX: CGFloat(), tY: CGFloat()
         )
     }
-    
-    // Translating
+
+    /// Applies the specified translation factors to the transformation matrix.
     open func translateX(by deltaX: CGFloat, yBy deltaY: CGFloat) {
         let translation = AffineTransform(translationByX: deltaX, byY: deltaY)
-        transformStruct = translation.concatenated(transformStruct)
+        affineTransform = translation.concatenated(affineTransform)
     }
     
-    // Rotating
+    /// Applies a rotation factor (measured in degrees) to the transformation matrix.
     open func rotate(byDegrees angle: CGFloat) {
         let rotation = AffineTransform(rotationByDegrees: angle)
-        transformStruct = rotation.concatenated(transformStruct)
+        affineTransform = rotation.concatenated(affineTransform)
     }
+
+    /// Applies a rotation factor (measured in radians) to the transformation matrix.
     open func rotate(byRadians angle: CGFloat) {
         let rotation = AffineTransform(rotationByRadians: angle)
-        transformStruct = rotation.concatenated(transformStruct)
+        affineTransform = rotation.concatenated(affineTransform)
     }
     
-    // Scaling
+    /// Applies the specified scaling factor along both x and y axes to the transformation matrix.
     open func scale(by scale: CGFloat) {
         scaleX(by: scale, yBy: scale)
     }
 
+    /// Applies scaling factors to each axis of the transformation matrix.
     open func scaleX(by scaleX: CGFloat, yBy scaleY: CGFloat) {
         let scale = AffineTransform(scaleByX: scaleX, byY: scaleY)
-        transformStruct = scale.concatenated(transformStruct)
+        affineTransform = scale.concatenated(affineTransform)
     }
     
-    // Inverting
+    /// Replaces the matrix with its inverse matrix.
     open func invert() {
-        if let inverse = transformStruct.inverted() {
-            transformStruct = inverse
+        if let inverse = affineTransform.inverted() {
+            affineTransform = inverse
         }
         else {
             preconditionFailure("NSAffineTransform: Transform has no inverse")
         }
     }
     
-    // Transforming with transform
-    open func append(_ transform: NSAffineTransform) {
-        transformStruct = transformStruct.concatenated(transform.transformStruct)
+    /// Appends the specified matrix.
+    open func append(_ transform: AffineTransform) {
+        affineTransform = affineTransform.concatenated(transform)
     }
-    open func prepend(_ transform: NSAffineTransform) {
-        transformStruct = transform.transformStruct.concatenated(transformStruct)
+
+    /// Prepends the specified matrix.
+    open func prepend(_ transform: AffineTransform) {
+        affineTransform = transform.concatenated(affineTransform)
     }
     
-    // Transforming points and sizes
+    /// Applies the transform to the specified point and returns the result.
     open func transform(_ aPoint: NSPoint) -> NSPoint {
-        return transformStruct.transform(aPoint)
+        return affineTransform.transform(aPoint)
     }
 
+    /// Applies the transform to the specified size and returns the result.
     open func transform(_ aSize: NSSize) -> NSSize {
-        return transformStruct.transform(aSize)
+        return affineTransform.transform(aSize)
     }
-
-    // Transform Struct
-    open var transformStruct: AffineTransform
 }
 
 extension AffineTransform : _ObjectTypeBridgeable {
@@ -429,9 +487,7 @@
 
     @_semantics("convertToObjectiveC")
     public func _bridgeToObjectiveC() -> NSAffineTransform {
-        let t = NSAffineTransform()
-        t.transformStruct = self
-        return t
+        return NSAffineTransform(transform: self)
     }
 
     public static func _forceBridgeFromObjectiveC(_ x: NSAffineTransform, result: inout AffineTransform?) {
@@ -441,7 +497,8 @@
     }
 
     public static func _conditionallyBridgeFromObjectiveC(_ x: NSAffineTransform, result: inout AffineTransform?) -> Bool {
-        result = x.transformStruct
+        let ts = x.transformStruct
+        result = AffineTransform(m11: ts.m11, m12: ts.m12, m21: ts.m21, m22: ts.m22, tX: ts.tX, tY: ts.tY)
         return true // Can't fail
     }
 
diff --git a/Foundation/Data.swift b/Foundation/Data.swift
index 5398567..0102662 100644
--- a/Foundation/Data.swift
+++ b/Foundation/Data.swift
@@ -38,6 +38,22 @@
 import _SwiftFoundationOverlayShims
 import _SwiftCoreFoundationOverlayShims
     
+internal func __NSDataIsCompact(_ data: NSData) -> Bool {
+    if #available(OSX 10.10, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
+        return data._isCompact()
+    } else {
+        var compact = true
+        let len = data.length
+        data.enumerateBytes { (_, byteRange, stop) in
+            if byteRange.length != len {
+                compact = false
+            }
+            stop.pointee = true
+        }
+        return compact
+    }
+}
+
 @_silgen_name("__NSDataWriteToURL")
 internal func __NSDataWriteToURL(_ data: NSData, _ url: NSURL, _ options: UInt, _ error: NSErrorPointer) -> Bool
     
@@ -130,7 +146,7 @@
         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() {
+            if __NSDataIsCompact(d) {
                 let len = d.length
                 guard len > 0 else {
                     return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
@@ -161,7 +177,7 @@
                 return try apply(UnsafeRawBufferPointer(buffer))
             }
         case .customMutableReference(let d):
-            if d._isCompact() {
+            if __NSDataIsCompact(d) {
                 let len = d.length
                 guard len > 0 else {
                     return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
@@ -505,7 +521,7 @@
         case .mutable:
             return _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
         case .customReference(let d):
-            if d._isCompact() {
+            if __NSDataIsCompact(d) {
                 return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
             } else {
                 var byte: UInt8 = 0
@@ -519,7 +535,7 @@
                 return byte
             }
         case .customMutableReference(let d):
-            if d._isCompact() {
+            if __NSDataIsCompact(d) {
                 return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
             } else {
                 var byte: UInt8 = 0
@@ -1590,7 +1606,6 @@
     @inline(__always)
     public func subdata(in range: Range<Index>) -> Data {
         _validateRange(range)
-        let length = count
         if count == 0 {
             return Data()
         }
@@ -1627,9 +1642,11 @@
     public var hashValue: Int {
         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)
+        _withStackOrHeapBuffer(hashRange.count + 1) { buffer in
+            if hashRange.count > 0 {
+                _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))
         }
@@ -1926,27 +1943,11 @@
 
 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 = Data(count: count)
+            self.init(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.
@@ -1955,7 +1956,7 @@
                 self[i] = byte
             }
         } else {
-            self = Data()
+            self.init()
         }
         
         while !container.isAtEnd {
@@ -1965,21 +1966,6 @@
     }
     
     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.
diff --git a/Foundation/DateInterval.swift b/Foundation/DateInterval.swift
index 3a5d36a..0d22b7a 100644
--- a/Foundation/DateInterval.swift
+++ b/Foundation/DateInterval.swift
@@ -52,10 +52,7 @@
     ///
     /// - precondition: `end >= start`
     public init(start: Date, end: Date) {
-        if end < start {
-            fatalError("Reverse intervals are not allowed")
-        }
-        
+        precondition(end >= start, "Reverse intervals are not allowed")
         self.start = start
         duration = end.timeIntervalSince(start)
     }
diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift
index e5e2673..0148a38 100644
--- a/Foundation/FileManager.swift
+++ b/Foundation/FileManager.swift
@@ -343,7 +343,38 @@
         This method replaces fileSystemAttributesAtPath:.
      */
     open func attributesOfFileSystem(forPath path: String) throws -> [FileAttributeKey : Any] {
+#if os(Android)
         NSUnimplemented()
+#else
+        // statvfs(2) doesn't support 64bit inode on Darwin (apfs), fallback to statfs(2)
+        #if os(OSX) || os(iOS)
+            var s = statfs()
+            guard statfs(path, &s) == 0 else {
+                throw _NSErrorWithErrno(errno, reading: true, path: path)
+            }
+        #else
+            var s = statvfs()
+            guard statvfs(path, &s) == 0 else {
+                throw _NSErrorWithErrno(errno, reading: true, path: path)
+            }
+        #endif
+        
+        
+        var result = [FileAttributeKey : Any]()
+        #if os(OSX) || os(iOS)
+            let blockSize = UInt64(s.f_bsize)
+            result[.systemNumber] = NSNumber(value: UInt64(s.f_fsid.val.0))
+        #else
+            let blockSize = UInt64(s.f_frsize)
+            result[.systemNumber] = NSNumber(value: UInt64(s.f_fsid))
+        #endif
+        result[.systemSize] = NSNumber(value: blockSize * UInt64(s.f_blocks))
+        result[.systemFreeSize] = NSNumber(value: blockSize * UInt64(s.f_bavail))
+        result[.systemNodes] = NSNumber(value: UInt64(s.f_files))
+        result[.systemFreeNodes] = NSNumber(value: UInt64(s.f_ffree))
+        
+        return result
+#endif
     }
     
     /* createSymbolicLinkAtPath:withDestination:error: returns YES if the symbolic link that point at 'destPath' was able to be created at the location specified by 'path'. If this method returns NO, the link was unable to be created and an NSError will be returned by reference in the 'error' parameter. This method does not traverse a terminal symlink.
diff --git a/Foundation/HTTPCookieStorage.swift b/Foundation/HTTPCookieStorage.swift
index 2209818..3c5e99e 100644
--- a/Foundation/HTTPCookieStorage.swift
+++ b/Foundation/HTTPCookieStorage.swift
@@ -77,8 +77,9 @@
     }
 
     private func loadPersistedCookies() {
-        guard let cookies = NSMutableDictionary(contentsOfFile: cookieFilePath) else { return }
-        var cookies0 = _SwiftValue.fetch(cookies) as? [String: [String: Any]] ?? [:]
+        guard let cookiesData = try? Data(contentsOf: URL(fileURLWithPath: cookieFilePath)) else { return }
+        guard let cookies = try? PropertyListSerialization.propertyList(from: cookiesData, format: nil) else { return }
+        var cookies0 = cookies as? [String: [String: Any]] ?? [:]
         self.syncQ.sync {
             for key in cookies0.keys {
                 if let cookie = createCookie(cookies0[key]!) {
diff --git a/Foundation/Host.swift b/Foundation/Host.swift
index 3c09f7c..64b979d 100644
--- a/Foundation/Host.swift
+++ b/Foundation/Host.swift
@@ -28,6 +28,10 @@
     internal var _names = [String]()
     internal var _addresses = [String]()
     
+#if os(Android)
+    static internal let NI_MAXHOST = 1025
+#endif
+    
     static internal let _current = Host(currentHostName(), .current)
     
     internal init(_ info: String?, _ type: ResolveType) {
@@ -65,6 +69,9 @@
     }
     
     internal func _resolveCurrent() {
+#if os(Android)
+        return
+#else
         var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
         if getifaddrs(&ifaddr) != 0 {
             return
@@ -88,9 +95,13 @@
             }
             ifa = ifaValue.ifa_next
         }
+#endif
     }
     
     internal func _resolve() {
+#if os(Android)
+        return
+#else
         if _resolved {
             return
         }
@@ -148,7 +159,7 @@
                 res = info.ai_next
             }
         }
-        
+#endif   
     }
     
     open var name: String? {
diff --git a/Foundation/JSONEncoder.swift b/Foundation/JSONEncoder.swift
index 5c36e1f..40ed9fa 100644
--- a/Foundation/JSONEncoder.swift
+++ b/Foundation/JSONEncoder.swift
@@ -101,7 +101,7 @@
     open var userInfo: [CodingUserInfoKey : Any] = [:]
 
     /// Options set on the top-level encoder to pass down the encoding hierarchy.
-    internal struct _Options {
+    fileprivate struct _Options {
         let dateEncodingStrategy: DateEncodingStrategy
         let dataEncodingStrategy: DataEncodingStrategy
         let nonConformingFloatEncodingStrategy: NonConformingFloatEncodingStrategy
@@ -153,14 +153,14 @@
 
 // MARK: - _JSONEncoder
 
-internal class _JSONEncoder : Encoder {
+fileprivate class _JSONEncoder : Encoder {
     // MARK: Properties
 
     /// The encoder's storage.
     fileprivate var storage: _JSONEncodingStorage
 
     /// Options set on the top-level encoder.
-    internal let options: JSONEncoder._Options
+    fileprivate let options: JSONEncoder._Options
 
     /// The path to the current point in encoding.
     public var codingPath: [CodingKey]
@@ -866,7 +866,7 @@
     open var userInfo: [CodingUserInfoKey : Any] = [:]
 
     /// Options set on the top-level encoder to pass down the decoding hierarchy.
-    internal struct _Options {
+    fileprivate struct _Options {
         let dateDecodingStrategy: DateDecodingStrategy
         let dataDecodingStrategy: DataDecodingStrategy
         let nonConformingFloatDecodingStrategy: NonConformingFloatDecodingStrategy
@@ -904,14 +904,14 @@
 
 // MARK: - _JSONDecoder
 
-internal class _JSONDecoder : Decoder {
+fileprivate class _JSONDecoder : Decoder {
     // MARK: Properties
 
     /// The decoder's storage.
     fileprivate var storage: _JSONDecodingStorage
 
     /// Options set on the top-level decoder.
-    internal let options: JSONDecoder._Options
+    fileprivate let options: JSONDecoder._Options
 
     /// The path to the current point in encoding.
     private(set) public var codingPath: [CodingKey]
diff --git a/Foundation/NSArray.swift b/Foundation/NSArray.swift
index 5b5d40f..d004ecc 100644
--- a/Foundation/NSArray.swift
+++ b/Foundation/NSArray.swift
@@ -27,18 +27,33 @@
         return _SwiftValue.fetch(nonOptional: _storage[index])
     }
     
-    public convenience override init() {
-        self.init(objects: [], count:0)
+    public override init() {
+        _storage.reserveCapacity(0)
     }
-    
-    public required init(objects: UnsafePointer<AnyObject>!, count cnt: Int) {
-        _storage.reserveCapacity(cnt)
-        for idx in 0..<cnt {
+
+    public required init(objects: UnsafePointer<AnyObject>?, count: Int) {
+        precondition(count >= 0)
+        precondition(count == 0 || objects != nil)
+
+        _storage.reserveCapacity(count)
+        for idx in 0..<count {
+            _storage.append(objects![idx])
+        }
+    }
+
+    public convenience init(objects: UnsafePointer<AnyObject>, count: Int) {
+        self.init()
+        _storage.reserveCapacity(count)
+        for idx in 0..<count {
             _storage.append(objects[idx])
         }
     }
-    
-    required public convenience init(arrayLiteral elements: Any...) {
+
+    public convenience init(objects elements: AnyObject...) {
+        self.init(objects: elements, count: elements.count)
+    }
+
+    public required convenience init(arrayLiteral elements: Any...) {
         self.init(array: elements)
     }
     
@@ -168,7 +183,7 @@
     open func addingObjects(from otherArray: [Any]) -> [Any] {
         return allObjects + otherArray
     }
-    
+
     open func componentsJoined(by separator: String) -> String {
         // make certain to call NSObject's description rather than asking the string interpolator for the swift description
         return allObjects.map { "\($0)" }.joined(separator: separator)
@@ -188,8 +203,15 @@
         }
         return false
     }
-    
-    open func description(withLocale locale: Locale?) -> String { return description(withLocale: locale, indent: 0) }
+
+    override open var description: String {
+        return description(withLocale: nil)
+    }
+
+    open func description(withLocale locale: Locale?) -> String {
+        return description(withLocale: locale, indent: 0)
+    }
+
     open func description(withLocale locale: Locale?, indent level: Int) -> String {
         var descriptions = [String]()
         let cnt = count
@@ -406,12 +428,19 @@
         getObjects(&objects, range: range)
         return objects
     }
-    
+
+    open func write(to url: URL) throws {
+        let pListData = try PropertyListSerialization.data(fromPropertyList: self, format: .xml, options: 0)
+        try pListData.write(to: url, options: .atomic)
+    }
+
+    @available(*, deprecated)
     open func write(toFile path: String, atomically useAuxiliaryFile: Bool) -> Bool {
         return write(to: URL(fileURLWithPath: path), atomically: useAuxiliaryFile)
     }
-    
+
     // the atomically flag is ignored if url of a type that cannot be written atomically.
+    @available(*, deprecated)
     open func write(to url: URL, atomically: Bool) -> Bool {
         do {
             let pListData = try PropertyListSerialization.data(fromPropertyList: self, format: .xml, options: 0)
@@ -421,7 +450,7 @@
             return false
         }
     }
-    
+
     open func objects(at indexes: IndexSet) -> [Any] {
         var objs = [Any]()
         indexes.rangeView.forEach {
@@ -430,7 +459,7 @@
         
         return objs
     }
-    
+
     open subscript (idx: Int) -> Any {
         guard idx < count && idx >= 0 else {
             fatalError("\(self): Index out of bounds")
@@ -438,25 +467,29 @@
         
         return object(at: idx)
     }
-    
+
     open func enumerateObjects(_ block: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         self.enumerateObjects(options: [], using: block)
     }
+
     open func enumerateObjects(options opts: NSEnumerationOptions = [], using block: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         self.enumerateObjects(at: IndexSet(integersIn: 0..<count), options: opts, using: block)
     }
+
     open func enumerateObjects(at s: IndexSet, options opts: NSEnumerationOptions = [], using block: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         s._bridgeToObjectiveC().enumerate(options: opts) { (idx, stop) in
             block(self.object(at: idx), idx, stop)
         }
     }
-    
+
     open func indexOfObject(passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> Int {
-        return indexOfObject([], passingTest: predicate)
+        return indexOfObject(options: [], passingTest: predicate)
     }
-    open func indexOfObject(_ opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> Int {
+
+    open func indexOfObject(options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> Int {
         return indexOfObject(at: IndexSet(integersIn: 0..<count), options: opts, passingTest: predicate)
     }
+
     open func indexOfObject(at s: IndexSet, options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> Int {
         var result = NSNotFound
         enumerateObjects(at: s, options: opts) { (obj, idx, stop) -> Void in
@@ -467,13 +500,15 @@
         }
         return result
     }
-    
+
     open func indexesOfObjects(passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet {
         return indexesOfObjects(options: [], passingTest: predicate)
     }
+
     open func indexesOfObjects(options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet {
         return indexesOfObjects(at: IndexSet(integersIn: 0..<count), options: opts, passingTest: predicate)
     }
+
     open func indexesOfObjects(at s: IndexSet, options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet {
         var result = IndexSet()
         enumerateObjects(at: s, options: opts) { (obj, idx, stop) in
@@ -589,22 +624,38 @@
         
         return lastEqual ? result + 1 : result
     }
-    
-    public convenience init?(contentsOfFile path: String) {
-        self.init(contentsOfURL: URL(fileURLWithPath: path))
+
+    public convenience init(contentsOf url: URL, error: ()) throws {
+        let plistDoc = try Data(contentsOf: url)
+        guard let plistArray = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Array<Any>
+            else {
+                throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: [NSURLErrorKey : url])
+        }
+        self.init(array: plistArray)
     }
-    
-    public convenience init?(contentsOfURL url: URL) {
+
+    @available(*, deprecated)
+    public convenience init?(contentsOfFile path: String) {
         do {
-            guard let plistDoc = try? Data(contentsOf: url),
-            let plistArray = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Array<Any>
-             else { return nil }
-            self.init(array: plistArray)
+            try self.init(contentsOf: URL(fileURLWithPath: path), error: ())
         } catch {
             return nil
         }
     }
-    
+
+    @available(*, deprecated)
+    public convenience init?(contentsOf url: URL) {
+        do {
+            try self.init(contentsOf: url, error: ())
+        } catch {
+            return nil
+        }
+    }
+
+    open func pathsMatchingExtensions(_ filterTypes: [String]) -> [String] {
+        NSUnimplemented()
+    }
+
     override open var _cfTypeID: CFTypeID {
         return CFArrayGetTypeID()
     }
@@ -664,7 +715,11 @@
         }
         _storage.insert(_SwiftValue.store(anObject), at: index)
     }
-    
+
+    open func insert(_ objects: [Any], at indexes: IndexSet) {
+        NSUnimplemented()
+    }
+
     open func removeLastObject() {
         if count > 0 {
             removeObject(at: count - 1)
@@ -687,22 +742,26 @@
         _storage.replaceSubrange(min..<max, with: [_SwiftValue.store(anObject) as AnyObject])
     }
     
-    public convenience init() {
-        self.init(capacity: 0)
+    public override init() {
+        super.init()
     }
     
     public init(capacity numItems: Int) {
-        super.init(objects: [], count: 0)
+        super.init(objects: nil, count: 0)
 
         if type(of: self) === NSMutableArray.self {
             _storage.reserveCapacity(numItems)
         }
     }
     
-    public required convenience init(objects: UnsafePointer<AnyObject>!, count cnt: Int) {
-        self.init(capacity: cnt)
-        for idx in 0..<cnt {
-            _storage.append(objects[idx])
+    public required init(objects: UnsafePointer<AnyObject>?, count: Int) {
+        precondition(count >= 0)
+        precondition(count == 0 || objects != nil)
+
+        super.init()
+        _storage.reserveCapacity(count)
+        for idx in 0..<count {
+            _storage.append(objects![idx])
         }
     }
     
@@ -715,7 +774,7 @@
         }
     }
     
-    open func addObjectsFromArray(_ otherArray: [Any]) {
+    open func addObjects(from otherArray: [Any]) {
         if type(of: self) === NSMutableArray.self {
             _storage += otherArray.map { _SwiftValue.store($0) as AnyObject }
         } else {
@@ -743,7 +802,7 @@
         }
     }
     
-    open func remove(_ anObject: Any, inRange range: NSRange) {
+    open func remove(_ anObject: Any, in range: NSRange) {
         let idx = index(of: anObject, in: range)
         if idx != NSNotFound {
             removeObject(at: idx)
@@ -757,7 +816,7 @@
         }
     }
     
-    open func removeObject(identicalTo anObject: Any, inRange range: NSRange) {
+    open func removeObject(identicalTo anObject: Any, in range: NSRange) {
         let idx = indexOfObjectIdentical(to: anObject, in: range)
         if idx != NSNotFound {
             removeObject(at: idx)
@@ -794,10 +853,10 @@
     open func replaceObjects(in range: NSRange, withObjectsFrom otherArray: [Any], range otherRange: NSRange) {
         var list = [Any]()
         otherArray._bridgeToObjectiveC().getObjects(&list, range:otherRange)
-        replaceObjects(in: range, withObjectsFromArray:list)
+        replaceObjects(in: range, withObjectsFrom: list)
     }
     
-    open func replaceObjects(in range: NSRange, withObjectsFromArray otherArray: [Any]) {
+    open func replaceObjects(in range: NSRange, withObjectsFrom otherArray: [Any]) {
         if type(of: self) === NSMutableArray.self {
             _storage.reserveCapacity(count - range.length + otherArray.count)
             for idx in 0..<range.length {
@@ -815,7 +874,7 @@
         if type(of: self) === NSMutableArray.self {
             _storage = otherArray.map { _SwiftValue.store($0) }
         } else {
-            replaceObjects(in: NSMakeRange(0, count), withObjectsFromArray: otherArray)
+            replaceObjects(in: NSMakeRange(0, count), withObjectsFrom: otherArray)
         }
     }
     
@@ -844,7 +903,7 @@
         for countedRange in indexes.rangeView {
             let range = NSMakeRange(countedRange.lowerBound, countedRange.upperBound - countedRange.lowerBound)
             let subObjects = objects[objectIndex..<objectIndex + range.length]
-            self.replaceObjects(in: range, withObjectsFromArray: Array(subObjects))
+            self.replaceObjects(in: range, withObjectsFrom: Array(subObjects))
             objectIndex += range.length
         }
     }
@@ -853,11 +912,11 @@
         self.setArray(self.sortedArray(compare, context: context))
     }
 
-    open func sort(_ cmptr: Comparator) {
-        self.sort(options: [], usingComparator: cmptr)
+    open func sort(comparator: Comparator) {
+        self.sort(options: [], usingComparator: comparator)
     }
 
-    open func sort(options opts: NSSortOptions, usingComparator cmptr: Comparator) {
+    open func sort(options opts: NSSortOptions = [], usingComparator cmptr: Comparator) {
         self.setArray(self.sortedArray(options: opts, usingComparator: cmptr))
     }
     
diff --git a/Foundation/NSAttributedString.swift b/Foundation/NSAttributedString.swift
index 3877813..de1464b 100644
--- a/Foundation/NSAttributedString.swift
+++ b/Foundation/NSAttributedString.swift
@@ -9,6 +9,22 @@
 
 import CoreFoundation
 
+public struct NSAttributedStringKey : RawRepresentable, Equatable, Hashable {
+    public let rawValue: String
+
+    public init(_ rawValue: String) {
+        self.rawValue = rawValue
+    }
+
+    public init(rawValue: String) {
+        self.rawValue = rawValue
+    }
+
+    public var hashValue: Int {
+        return rawValue.hashValue
+    }
+}
+
 open class NSAttributedString: NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
     
     private let _cfinfo = _CFInfo(typeID: CFAttributedStringGetTypeID())
@@ -42,12 +58,14 @@
     open func mutableCopy(with zone: NSZone? = nil) -> Any {
         NSUnimplemented()
     }
-    
+
+    /// The character contents of the receiver as an NSString object.
     open var string: String {
         return _string._swiftObject
     }
-    
-    open func attributes(at location: Int, effectiveRange range: NSRangePointer) -> [String : Any] {
+
+    /// Returns the attributes for the character at a given index.
+    open func attributes(at location: Int, effectiveRange range: NSRangePointer?) -> [NSAttributedStringKey : Any] {
         let rangeInfo = RangeInfo(
             rangePointer: range,
             shouldFetchLongestEffectiveRange: false,
@@ -55,60 +73,72 @@
         return _attributes(at: location, rangeInfo: rangeInfo)
     }
 
+    /// The length of the receiver’s string object.
     open var length: Int {
         return CFAttributedStringGetLength(_cfObject)
     }
-    
-    open func attribute(_ attrName: String, at location: Int, effectiveRange range: NSRangePointer?) -> Any? {
+
+    /// Returns the value for an attribute with a given name of the character at a given index, and by reference the range over which the attribute applies.
+    open func attribute(_ attrName: NSAttributedStringKey, at location: Int, effectiveRange range: NSRangePointer?) -> Any? {
         let rangeInfo = RangeInfo(
             rangePointer: range,
             shouldFetchLongestEffectiveRange: false,
             longestEffectiveRangeSearchRange: nil)
         return _attribute(attrName, atIndex: location, rangeInfo: rangeInfo)
     }
-    
+
+    /// Returns an NSAttributedString object consisting of the characters and attributes within a given range in the receiver.
     open func attributedSubstring(from range: NSRange) -> NSAttributedString { NSUnimplemented() }
-    
-    open func attributes(at location: Int, longestEffectiveRange range: NSRangePointer?, in rangeLimit: NSRange) -> [String : Any] {
+
+    /// Returns the attributes for the character at a given index, and by reference the range over which the attributes apply.
+    open func attributes(at location: Int, longestEffectiveRange range: NSRangePointer?, in rangeLimit: NSRange) -> [NSAttributedStringKey : Any] {
         let rangeInfo = RangeInfo(
             rangePointer: range,
             shouldFetchLongestEffectiveRange: true,
             longestEffectiveRangeSearchRange: rangeLimit)
         return _attributes(at: location, rangeInfo: rangeInfo)
     }
-    
-    open func attribute(_ attrName: String, at location: Int, longestEffectiveRange range: NSRangePointer?, in rangeLimit: NSRange) -> Any? {
+
+    /// Returns the value for the attribute with a given name of the character at a given index, and by reference the range over which the attribute applies.
+    open func attribute(_ attrName: NSAttributedStringKey, at location: Int, longestEffectiveRange range: NSRangePointer?, in rangeLimit: NSRange) -> Any? {
         let rangeInfo = RangeInfo(
             rangePointer: range,
             shouldFetchLongestEffectiveRange: true,
             longestEffectiveRangeSearchRange: rangeLimit)
         return _attribute(attrName, atIndex: location, rangeInfo: rangeInfo)
     }
-    
+
+    /// Returns a Boolean value that indicates whether the receiver is equal to another given attributed string.
     open func isEqual(to other: NSAttributedString) -> Bool { NSUnimplemented() }
-    
-    public init(string str: String) {
-        _string = str._nsObject
+
+    /// Returns an NSAttributedString object initialized with the characters of a given string and no attribute information.
+    public init(string: String) {
+        _string = string._nsObject
         _attributeArray = CFRunArrayCreate(kCFAllocatorDefault)
         
         super.init()
         addAttributesToAttributeArray(attrs: nil)
     }
-    
-    public init(string str: String, attributes attrs: [String : Any]?) {
-        _string = str._nsObject
+
+    /// Returns an NSAttributedString object initialized with a given string and attributes.
+    public init(string: String, attributes attrs: [NSAttributedStringKey : Any]? = nil) {
+        _string = string._nsObject
         _attributeArray = CFRunArrayCreate(kCFAllocatorDefault)
-        
+
         super.init()
         addAttributesToAttributeArray(attrs: attrs)
     }
-    
-    public init(NSAttributedString attrStr: NSAttributedString) { NSUnimplemented() }
 
-    open func enumerateAttributes(in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: ([String : Any], NSRange, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
+    /// Returns an NSAttributedString object initialized with the characters and attributes of another given attributed string.
+    public init(attributedString: NSAttributedString) {
+        NSUnimplemented()
+    }
+
+    /// Executes the block for each attribute in the range.
+    open func enumerateAttributes(in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: ([NSAttributedStringKey : Any], NSRange, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         _enumerate(in: enumerationRange, reversed: opts.contains(.reverse)) { currentIndex, stop in
             var attributesEffectiveRange = NSRange(location: NSNotFound, length: 0)
-            let attributesInRange: [String : Any]
+            let attributesInRange: [NSAttributedStringKey : Any]
             if opts.contains(.longestEffectiveRangeNotRequired) {
                 attributesInRange = attributes(at: currentIndex, effectiveRange: &attributesEffectiveRange)
             } else {
@@ -122,8 +152,9 @@
             return attributesEffectiveRange
         }
     }
-    
-    open func enumerateAttribute(_ attrName: String, in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: (Any?, NSRange, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
+
+    /// Executes the block for the specified attribute run in the specified range.
+    open func enumerateAttribute(_ attrName: NSAttributedStringKey, in enumerationRange: NSRange, options opts: NSAttributedString.EnumerationOptions = [], using block: (Any?, NSRange, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
         _enumerate(in: enumerationRange, reversed: opts.contains(.reverse)) { currentIndex, stop in
             var attributeEffectiveRange = NSRange(location: NSNotFound, length: 0)
             let attributeInRange: Any?
@@ -183,9 +214,9 @@
         let longestEffectiveRangeSearchRange: NSRange?
     }
     
-    func _attributes(at location: Int, rangeInfo: RangeInfo) -> [String : Any] {
+    func _attributes(at location: Int, rangeInfo: RangeInfo) -> [NSAttributedStringKey : Any] {
         var cfRange = CFRange()
-        return withUnsafeMutablePointer(to: &cfRange) { (cfRangePointer: UnsafeMutablePointer<CFRange>) -> [String : Any] in
+        return withUnsafeMutablePointer(to: &cfRange) { (cfRangePointer: UnsafeMutablePointer<CFRange>) -> [NSAttributedStringKey : Any] in
             // Get attributes value using CoreFoundation function
             let value: CFDictionary
             if rangeInfo.shouldFetchLongestEffectiveRange, let searchRange = rangeInfo.longestEffectiveRangeSearchRange {
@@ -196,12 +227,12 @@
             
             // Convert the value to [String : AnyObject]
             let dictionary = unsafeBitCast(value, to: NSDictionary.self)
-            var results = [String : Any]()
+            var results = [NSAttributedStringKey : Any]()
             for (key, value) in dictionary {
                 guard let stringKey = (key as? NSString)?._swiftObject else {
                     continue
                 }
-                results[stringKey] = value
+                results[NSAttributedStringKey(stringKey)] = value
             }
             
             // Update effective range and return the results
@@ -211,15 +242,15 @@
         }
     }
     
-    func _attribute(_ attrName: String, atIndex location: Int, rangeInfo: RangeInfo) -> Any? {
+    func _attribute(_ attrName: NSAttributedStringKey, atIndex location: Int, rangeInfo: RangeInfo) -> Any? {
         var cfRange = CFRange()
         return withUnsafeMutablePointer(to: &cfRange) { (cfRangePointer: UnsafeMutablePointer<CFRange>) -> AnyObject? in
             // Get attribute value using CoreFoundation function
             let attribute: AnyObject?
             if rangeInfo.shouldFetchLongestEffectiveRange, let searchRange = rangeInfo.longestEffectiveRangeSearchRange {
-                attribute = CFAttributedStringGetAttributeAndLongestEffectiveRange(_cfObject, location, attrName._cfObject, CFRange(searchRange), cfRangePointer)
+                attribute = CFAttributedStringGetAttributeAndLongestEffectiveRange(_cfObject, location, attrName.rawValue._cfObject, CFRange(searchRange), cfRangePointer)
             } else {
-                attribute = CFAttributedStringGetAttribute(_cfObject, location, attrName._cfObject, cfRangePointer)
+                attribute = CFAttributedStringGetAttribute(_cfObject, location, attrName.rawValue._cfObject, cfRangePointer)
             }
             
             // Update effective range and return the result
@@ -241,18 +272,17 @@
         }
     }
     
-    func addAttributesToAttributeArray(attrs: [String : Any]?) {
+    func addAttributesToAttributeArray(attrs: [NSAttributedStringKey : Any]?) {
         guard _string.length > 0 else {
             return
         }
         
         let range = CFRange(location: 0, length: _string.length)
+        var attributes: [String : Any] = [:]
         if let attrs = attrs {
-            CFRunArrayInsert(_attributeArray, range, attrs._cfObject)
-        } else {
-            let emptyAttrs = [String : AnyObject]()
-            CFRunArrayInsert(_attributeArray, range, emptyAttrs._cfObject)
+            attrs.forEach { attributes[$0.rawValue] = $1 }
         }
+        CFRunArrayInsert(_attributeArray, range, attributes._cfObject)
     }
 }
 
@@ -277,19 +307,19 @@
 open class NSMutableAttributedString : NSAttributedString {
     
     open func replaceCharacters(in range: NSRange, with str: String) { NSUnimplemented() }
-    open func setAttributes(_ attrs: [String : Any]?, range: NSRange) { NSUnimplemented() }
+    open func setAttributes(_ attrs: [NSAttributedStringKey : Any]?, range: NSRange) { NSUnimplemented() }
     
     open var mutableString: NSMutableString {
         return _string as! NSMutableString
     }
-    
-    open func addAttribute(_ name: String, value: Any, range: NSRange) {
-        CFAttributedStringSetAttribute(_cfMutableObject, CFRange(range), name._cfObject, _SwiftValue.store(value))
+
+    open func addAttribute(_ name: NSAttributedStringKey, value: Any, range: NSRange) {
+        CFAttributedStringSetAttribute(_cfMutableObject, CFRange(range), name.rawValue._cfObject, _SwiftValue.store(value))
     }
+
+    open func addAttributes(_ attrs: [NSAttributedStringKey : Any], range: NSRange) { NSUnimplemented() }
     
-    open func addAttributes(_ attrs: [String : Any], range: NSRange) { NSUnimplemented() }
-    
-    open func removeAttribute(_ name: String, range: NSRange) { NSUnimplemented() }
+    open func removeAttribute(_ name: NSAttributedStringKey, range: NSRange) { NSUnimplemented() }
     
     open func replaceCharacters(in range: NSRange, with attrString: NSAttributedString) { NSUnimplemented() }
     open func insert(_ attrString: NSAttributedString, at loc: Int) { NSUnimplemented() }
diff --git a/Foundation/NSCFArray.swift b/Foundation/NSCFArray.swift
index b7ba101..c2a1e7d 100644
--- a/Foundation/NSCFArray.swift
+++ b/Foundation/NSCFArray.swift
@@ -20,7 +20,7 @@
         fatalError()
     }
     
-    required init(objects: UnsafePointer<AnyObject>!, count cnt: Int) {
+    required init(objects: UnsafePointer<AnyObject>?, count cnt: Int) {
         fatalError()
     }
     
@@ -126,5 +126,5 @@
 
 internal func _CFSwiftArrayReplaceValues(_ array: AnyObject, _ range: CFRange, _ newValues: UnsafeMutablePointer<Unmanaged<AnyObject>>, _ newCount: CFIndex) {
     NSUnimplemented()
-//    (array as! NSMutableArray).replaceObjectsInRange(NSMakeRange(range.location, range.length), withObjectsFromArray: newValues.array(newCount))
+//    (array as! NSMutableArray).replaceObjectsInRange(NSMakeRange(range.location, range.length), withObjectsFrom: newValues.array(newCount))
 }
diff --git a/Foundation/NSLocale.swift b/Foundation/NSLocale.swift
index 4b1b44f..f6ba25a 100644
--- a/Foundation/NSLocale.swift
+++ b/Foundation/NSLocale.swift
@@ -50,6 +50,10 @@
         self.init(localeIdentifier: String._unconditionallyBridgeFromObjectiveC(identifier))
     }
     
+    deinit {
+        _CFDeinit(self)
+    }
+    
     open override func copy() -> Any {
         return copy(with: nil)
     }
diff --git a/Foundation/NSLock.swift b/Foundation/NSLock.swift
index f4b41d0..886b5ba 100644
--- a/Foundation/NSLock.swift
+++ b/Foundation/NSLock.swift
@@ -1,6 +1,6 @@
 // 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
@@ -21,39 +21,71 @@
     func unlock()
 }
 
-open class NSLock: NSObject, NSLocking {
 #if CYGWIN
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
+private typealias _PthreadMutexPointer = UnsafeMutablePointer<pthread_mutex_t?>
+private typealias _PthreadCondPointer = UnsafeMutablePointer<pthread_cond_t?>
 #else
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
+private typealias _PthreadMutexPointer = UnsafeMutablePointer<pthread_mutex_t>
+private typealias _PthreadCondPointer = UnsafeMutablePointer<pthread_cond_t>
 #endif
-    
+
+open class NSLock: NSObject, NSLocking {
+    internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
+#if os(OSX) || os(iOS)
+    private var timeoutCond = _PthreadCondPointer.allocate(capacity: 1)
+    private var timeoutMutex = _PthreadMutexPointer.allocate(capacity: 1)
+#endif
+
     public override init() {
         pthread_mutex_init(mutex, nil)
+#if os(OSX) || os(iOS)
+        pthread_cond_init(timeoutCond, nil)
+        pthread_mutex_init(timeoutMutex, nil)
+#endif
     }
     
     deinit {
         pthread_mutex_destroy(mutex)
         mutex.deinitialize()
         mutex.deallocate(capacity: 1)
+#if os(OSX) || os(iOS)
+        deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
+#endif
     }
     
     open func lock() {
         pthread_mutex_lock(mutex)
     }
-    
+
     open func unlock() {
         pthread_mutex_unlock(mutex)
+#if os(OSX) || os(iOS)
+        // Wakeup any threads waiting in lock(before:)
+        pthread_mutex_lock(timeoutMutex)
+        pthread_cond_broadcast(timeoutCond)
+        pthread_mutex_unlock(timeoutMutex)
+#endif
     }
-    
+
     open func `try`() -> Bool {
         return pthread_mutex_trylock(mutex) == 0
     }
     
-    open func lock(before limit: Date) {
-        NSUnimplemented()
+    open func lock(before limit: Date) -> Bool {
+        if pthread_mutex_trylock(mutex) == 0 {
+            return true
+        }
+
+#if os(OSX) || os(iOS)
+        return timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
+#else
+        guard var endTime = timeSpecFrom(date: limit) else {
+            return false
+        }
+        return pthread_mutex_timedlock(mutex, &endTime) == 0
+#endif
     }
-    
+
     open var name: String?
 }
 
@@ -143,12 +175,12 @@
 }
 
 open class NSRecursiveLock: NSObject, NSLocking {
-#if CYGWIN
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
-#else
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
+    internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
+#if os(OSX) || os(iOS)
+    private var timeoutCond = _PthreadCondPointer.allocate(capacity: 1)
+    private var timeoutMutex = _PthreadMutexPointer.allocate(capacity: 1)
 #endif
-    
+
     public override init() {
         super.init()
 #if CYGWIN
@@ -166,6 +198,9 @@
         pthread_mutex_destroy(mutex)
         mutex.deinitialize()
         mutex.deallocate(capacity: 1)
+#if os(OSX) || os(iOS)
+        deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
+#endif
     }
     
     open func lock() {
@@ -174,28 +209,40 @@
     
     open func unlock() {
         pthread_mutex_unlock(mutex)
+#if os(OSX) || os(iOS)
+        // Wakeup any threads waiting in lock(before:)
+        pthread_mutex_lock(timeoutMutex)
+        pthread_cond_broadcast(timeoutCond)
+        pthread_mutex_unlock(timeoutMutex)
+#endif
     }
     
     open func `try`() -> Bool {
         return pthread_mutex_trylock(mutex) == 0
     }
     
-    open func lock(before limit: Date) {
-        NSUnimplemented()
+    open func lock(before limit: Date) -> Bool {
+        if pthread_mutex_trylock(mutex) == 0 {
+            return true
+        }
+
+#if os(OSX) || os(iOS)
+        return timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
+#else
+        guard var endTime = timeSpecFrom(date: limit) else {
+            return false
+        }
+        return pthread_mutex_timedlock(mutex, &endTime) == 0
+#endif
     }
 
     open var name: String?
 }
 
 open class NSCondition: NSObject, NSLocking {
-#if CYGWIN
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
-    internal var cond = UnsafeMutablePointer<pthread_cond_t?>.allocate(capacity: 1)
-#else
-    internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
-    internal var cond = UnsafeMutablePointer<pthread_cond_t>.allocate(capacity: 1)
-#endif
-    
+    internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
+    internal var cond = _PthreadCondPointer.allocate(capacity: 1)
+
     public override init() {
         pthread_mutex_init(mutex, nil)
         pthread_cond_init(cond, nil)
@@ -221,31 +268,12 @@
     open func wait() {
         pthread_cond_wait(cond, mutex)
     }
-    
+
     open func wait(until limit: Date) -> Bool {
-        let lim = limit.timeIntervalSinceReferenceDate
-        let ti = lim - CFAbsoluteTimeGetCurrent()
-        if ti < 0.0 {
+        guard var timeout = timeSpecFrom(date: limit) else {
             return false
         }
-        var ts = timespec()
-        ts.tv_sec = Int(floor(ti))
-        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) * 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)
-        }
-
-        return retVal == 0
+        return pthread_cond_timedwait(cond, mutex, &timeout) == 0
     }
     
     open func signal() {
@@ -258,3 +286,58 @@
     
     open var name: String?
 }
+
+private func timeSpecFrom(date: Date) -> timespec? {
+    guard date.timeIntervalSinceNow > 0 else {
+        return nil
+    }
+    let nsecPerSec: Int64 = 1_000_000_000
+    let interval = date.timeIntervalSince1970
+    let intervalNS = Int64(interval * Double(nsecPerSec))
+
+    return timespec(tv_sec: Int(intervalNS / nsecPerSec),
+                    tv_nsec: Int(intervalNS % nsecPerSec))
+}
+
+#if os(OSX) || os(iOS)
+
+private func deallocateTimedLockData(cond: _PthreadCondPointer, mutex: _PthreadMutexPointer) {
+    pthread_cond_destroy(cond)
+    cond.deinitialize()
+    cond.deallocate(capacity: 1)
+
+    pthread_mutex_destroy(mutex)
+    mutex.deinitialize()
+    mutex.deallocate(capacity: 1)
+}
+
+// Emulate pthread_mutex_timedlock using pthread_cond_timedwait.
+// lock(before:) passes a condition variable/mutex pair to use.
+// unlock() will use pthread_cond_broadcast() to wake any waits in progress.
+private func timedLock(mutex: _PthreadMutexPointer, endTime: Date,
+                       using timeoutCond: _PthreadCondPointer,
+                       with timeoutMutex: _PthreadMutexPointer) -> Bool {
+
+    var timeSpec = timeSpecFrom(date: endTime)
+    while var ts = timeSpec {
+        let lockval = pthread_mutex_lock(timeoutMutex)
+        precondition(lockval == 0)
+        let waitval = pthread_cond_timedwait(timeoutCond, timeoutMutex, &ts)
+        precondition(waitval == 0 || waitval == ETIMEDOUT)
+        let unlockval = pthread_mutex_unlock(timeoutMutex)
+        precondition(unlockval == 0)
+
+        if waitval == ETIMEDOUT {
+            return false
+        }
+        let tryval = pthread_mutex_trylock(mutex)
+        precondition(tryval == 0 || tryval == EBUSY)
+        if tryval == 0 { // The lock was obtained.
+            return true
+        }
+        // pthread_cond_timedwait didnt timeout so wait some more.
+        timeSpec = timeSpecFrom(date: endTime)
+    }
+    return false
+}
+#endif
diff --git a/Foundation/NSObject.swift b/Foundation/NSObject.swift
index 2c5956f..bd4fe38 100644
--- a/Foundation/NSObject.swift
+++ b/Foundation/NSObject.swift
@@ -7,6 +7,11 @@
 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 
+// @_exported import of Dispatch here makes it available to all
+// classes in Foundation and all sources that import Foundation.
+// This brings it into line with Darwin usage for compatbility.
+@_exported import Dispatch
+
 import CoreFoundation
 
 /// The `NSObjectProtocol` groups methods that are fundamental to all Foundation objects.
diff --git a/Foundation/NSString.swift b/Foundation/NSString.swift
index b27719a..fcf11d7 100644
--- a/Foundation/NSString.swift
+++ b/Foundation/NSString.swift
@@ -20,6 +20,16 @@
     }
 }
 
+/// Returns a localized string, using the main bundle if one is not specified.
+public
+func NSLocalizedString(_ key: String,
+                       tableName: String? = nil,
+                       bundle: Bundle = Bundle.main,
+                       value: String = "",
+                       comment: String) -> String {
+    return bundle.localizedString(forKey: key, value: value, table: tableName)
+}
+
 #if os(OSX) || os(iOS)
 internal let kCFStringEncodingMacRoman =  CFStringBuiltInEncodings.macRoman.rawValue
 internal let kCFStringEncodingWindowsLatin1 =  CFStringBuiltInEncodings.windowsLatin1.rawValue
@@ -271,7 +281,10 @@
     }
     
     public convenience init?(cString nullTerminatedCString: UnsafePointer<Int8>, encoding: UInt) {
-        self.init(string: CFStringCreateWithCString(kCFAllocatorSystemDefault, nullTerminatedCString, CFStringConvertNSStringEncodingToEncoding(encoding))._swiftObject)
+        guard let str = CFStringCreateWithCString(kCFAllocatorSystemDefault, nullTerminatedCString, CFStringConvertNSStringEncodingToEncoding(encoding)) else {
+            return nil
+        }
+        self.init(string: str._swiftObject)
     }
     
     internal func _fastCStringContents(_ nullTerminated: Bool) -> UnsafePointer<Int8>? {
diff --git a/Foundation/NSTimeZone.swift b/Foundation/NSTimeZone.swift
index f022dfa..0d64795 100644
--- a/Foundation/NSTimeZone.swift
+++ b/Foundation/NSTimeZone.swift
@@ -29,6 +29,15 @@
     }
 
     public init?(name tzName: String, data aData: Data?) {
+#if os(Android)
+        var tzName = tzName
+        if tzName == "UTC" || tzName == "GMT" {
+            tzName = "GMT+0000"
+        }
+        else if !(tzName.hasPrefix("GMT+") || tzName.hasPrefix("GMT-")) {
+            NSLog("Time zone database not available on Android")
+        }
+#endif
         super.init()
         if !_CFTimeZoneInit(_cfObject, tzName._cfObject, aData?._cfObject) {
             return nil
@@ -170,6 +179,14 @@
 extension NSTimeZone {
 
     open class var system: TimeZone {
+#if os(Android)
+        var now = time(nil), info = tm()
+        if localtime_r(&now, &info) != nil {
+            // NOTE: this is not a real time zone but a fixed offset from GMT.
+            // It will be incorrect outside the current daylight saving period.
+            return TimeZone(reference: NSTimeZone(forSecondsFromGMT: info.tm_gmtoff))
+        }
+#endif
         return CFTimeZoneCopySystem()._swiftObject
     }
 
diff --git a/Foundation/Stream.swift b/Foundation/Stream.swift
index d34949d..410be23 100644
--- a/Foundation/Stream.swift
+++ b/Foundation/Stream.swift
@@ -241,11 +241,11 @@
 #endif
 
 extension StreamDelegate {
-    func stream(_ aStream: Stream, handleEvent eventCode: Stream.Event) { }
+    func stream(_ aStream: Stream, handle eventCode: Stream.Event) { }
 }
 
 public protocol StreamDelegate : class {
-    func stream(_ aStream: Stream, handleEvent eventCode: Stream.Event)
+    func stream(_ aStream: Stream, handle eventCode: Stream.Event)
 }
 
 // MARK: -
diff --git a/Foundation/Thread.swift b/Foundation/Thread.swift
index 402294d..dae27cd 100644
--- a/Foundation/Thread.swift
+++ b/Foundation/Thread.swift
@@ -256,7 +256,11 @@
         let maxSupportedStackDepth = 128;
         let addrs = UnsafeMutablePointer<UnsafeMutableRawPointer?>.allocate(capacity: maxSupportedStackDepth)
         defer { addrs.deallocate(capacity: maxSupportedStackDepth) }
+#if os(Android)
+        let count = 0
+#else
         let count = backtrace(addrs, Int32(maxSupportedStackDepth))
+#endif
         let addressCount = max(0, min(Int(count), maxSupportedStackDepth))
         return body(addrs, addressCount)
     }
@@ -270,6 +274,9 @@
     }
 
     open class var callStackSymbols: [String] {
+#if os(Android)
+        return []
+#else
         return backtraceAddresses({ (addrs, count) in
             var symbols: [String] = []
             if let bs = backtrace_symbols(addrs, Int32(count)) {
@@ -283,6 +290,7 @@
             }
             return symbols
         })
+#endif
     }
 }
 
diff --git a/Foundation/URLSession/URLSessionConfiguration.swift b/Foundation/URLSession/URLSessionConfiguration.swift
index a83f34e..70925cd 100644
--- a/Foundation/URLSession/URLSessionConfiguration.swift
+++ b/Foundation/URLSession/URLSessionConfiguration.swift
@@ -209,4 +209,22 @@
      */
      open var protocolClasses: [AnyClass]?
 
+     /* A Boolean value that indicates whether the session should wait for connectivity to become available, or fail immediately */
+     @available(*, unavailable, message: "Not available on non-Darwin platforms")
+     open var waitsForConnectivity: Bool { NSUnsupported() }
+
+     /* A service type that specifies the Multipath TCP connection policy for transmitting data over Wi-Fi and cellular interfaces*/
+     @available(*, unavailable, message: "Not available on non-Darwin platforms")
+     open var multipathServiceType: URLSessionConfiguration.MultipathServiceType { NSUnsupported() }
+
+}
+
+@available(*, unavailable, message: "Not available on non-Darwin platforms")
+extension URLSessionConfiguration {
+    public enum MultipathServiceType {
+        case none
+        case handover
+        case interactive
+        case aggregate
+    }
 }
diff --git a/Foundation/URLSession/http/EasyHandle.swift b/Foundation/URLSession/http/EasyHandle.swift
index ea0356d..02ae3d2 100644
--- a/Foundation/URLSession/http/EasyHandle.swift
+++ b/Foundation/URLSession/http/EasyHandle.swift
@@ -56,9 +56,7 @@
     fileprivate var headerList: _CurlStringList?
     fileprivate var pauseState: _PauseState = []
     internal var timeoutTimer: _TimeoutSource!
-    #if os(Android)
-    static fileprivate var _CAInfoFile: UnsafeMutablePointer<Int8>?
-    #endif
+    internal lazy var errorBuffer = [UInt8](repeating: 0, count: Int(CFURLSessionEasyErrorSize))
 
     init(delegate: _EasyHandleDelegate) {
         self.delegate = delegate
@@ -89,8 +87,8 @@
 }
 
 internal extension _EasyHandle {
-    func completedTransfer(withErrorCode errorCode: Int?) {
-        delegate?.transferCompleted(withErrorCode: errorCode)
+    func completedTransfer(withError error: NSError?) {
+        delegate?.transferCompleted(withError: error)
     }
 }
 internal protocol _EasyHandleDelegate: class {
@@ -107,7 +105,7 @@
     func fill(writeBuffer buffer: UnsafeMutableBufferPointer<Int8>) -> _EasyHandle._WriteBufferResult
     /// The transfer for this handle completed.
     /// - parameter errorCode: An NSURLError code, or `nil` if no error occured.
-    func transferCompleted(withErrorCode errorCode: Int?)
+    func transferCompleted(withError error: NSError?)
     /// Seek the input stream to the given position
     func seekInputStream(to position: UInt64) throws
     /// Gets called during the transfer to update progress.
@@ -146,7 +144,8 @@
     /// Set error buffer for error messages
     /// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_ERRORBUFFER.html
     func set(errorBuffer buffer: UnsafeMutableBufferPointer<UInt8>?) {
-        try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionERRORBUFFER, buffer?.baseAddress ?? nil).asError()
+        let buffer = buffer ?? errorBuffer.withUnsafeMutableBufferPointer { $0 }
+        try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionERRORBUFFER, buffer.baseAddress).asError()
     }
     /// Request failure on HTTP response >= 400
     func set(failOnHTTPErrorCode flag: Bool) {
@@ -170,20 +169,20 @@
         let protocols = (CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS)
         try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionPROTOCOLS, protocols).asError()
         try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionREDIR_PROTOCOLS, protocols).asError()
-        #if os(Android)
-            // See https://curl.haxx.se/docs/sslcerts.html
-            // For SSL to work you need "cacert.pem" to be accessable
-            // at the path pointed to by the URLSessionCAInfo env var.
-            // Downloadable here: https://curl.haxx.se/ca/cacert.pem
-            if let caInfo = _EasyHandle._CAInfoFile  {
-                if String(cString: caInfo) == "UNSAFE_SSL_NOVERIFY" {
-                    try! CFURLSession_easy_setopt_int(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError()
-                }
-                else {
-                    try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError()
-                }
+#if os(Android)
+        // See https://curl.haxx.se/docs/sslcerts.html
+        // For SSL on Android you need a "cacert.pem" to be
+        // accessible at the path pointed to by this env var.
+        // Downloadable here: https://curl.haxx.se/ca/cacert.pem
+        if let caInfo = getenv("URLSessionCertificateAuthorityInfoFile")  {
+            if String(cString: caInfo) == "INSECURE_SSL_NO_VERIFY" {
+                try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError()
             }
-        #endif
+            else {
+                try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError()
+            }
+        }
+#endif
         //TODO: Added in libcurl 7.45.0
         //TODO: Set default protocol for schemeless URLs
         //CURLOPT_DEFAULT_PROTOCOL available only in libcurl 7.45.0
@@ -630,19 +629,6 @@
     }
 }
 
-#if os(Android)
-extension URLSession {
-
-    public static func setCAInfoFile(_ _CAInfoFile: String) {
-        free(_EasyHandle._CAInfoFile)
-        _CAInfoFile.withCString {
-            _EasyHandle._CAInfoFile = strdup($0)
-        }
-    }
-
-}
-#endif
-
 extension CFURLSessionEasyCode : Equatable {
     public static func ==(lhs: CFURLSessionEasyCode, rhs: CFURLSessionEasyCode) -> Bool {
         return lhs.value == rhs.value
diff --git a/Foundation/URLSession/http/HTTPURLProtocol.swift b/Foundation/URLSession/http/HTTPURLProtocol.swift
index 78aff84..7371889 100644
--- a/Foundation/URLSession/http/HTTPURLProtocol.swift
+++ b/Foundation/URLSession/http/HTTPURLProtocol.swift
@@ -134,7 +134,9 @@
             //     NSURLErrorNoPermissionsToReadFile
             //     NSURLErrorFileDoesNotExist
             self.internalState = .transferFailed
-            failWith(errorCode: errorCode(fileSystemError: e), request: request)
+            let error = NSError(domain: NSURLErrorDomain, code: errorCode(fileSystemError: e),
+                                userInfo: [NSLocalizedDescriptionKey: "File system error"])
+            failWith(error: error, request: request)
             return
         }
 
@@ -328,17 +330,19 @@
         case stream(InputStream)
     }
 
-    func failWith(errorCode: Int, request: URLRequest) {
+    func failWith(error: NSError, request: URLRequest) {
         //TODO: Error handling
         let userInfo: [String : Any]? = request.url.map {
             [
+                NSUnderlyingErrorKey: error,
                 NSURLErrorFailingURLErrorKey: $0,
                 NSURLErrorFailingURLStringErrorKey: $0.absoluteString,
+                NSLocalizedDescriptionKey: NSLocalizedString(error.localizedDescription, comment: "N/A")
                 ]
         }
-        let error = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: errorCode, userInfo: userInfo))
-        completeTask(withError: error)
-        self.client?.urlProtocol(self, didFailWithError: error)
+        let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: error.code, userInfo: userInfo))
+        completeTask(withError: urlError)
+        self.client?.urlProtocol(self, didFailWithError: urlError)
     }
 }
 
@@ -528,16 +532,16 @@
         }
     }
 
-    func transferCompleted(withErrorCode errorCode: Int?) {
+    func transferCompleted(withError error: NSError?) {
         // At this point the transfer is complete and we can decide what to do.
         // If everything went well, we will simply forward the resulting data
         // to the delegate. But in case of redirects etc. we might send another
         // request.
         guard case .transferInProgress(let ts) = internalState else { fatalError("Transfer completed, but it wasn't in progress.") }
         guard let request = task?.currentRequest else { fatalError("Transfer completed, but there's no current request.") }
-        guard errorCode == nil else {
+        guard error == nil else {
             internalState = .transferFailed
-            failWith(errorCode: errorCode!, request: request)
+            failWith(error: error!, request: request)
             return
         }
 
@@ -555,7 +559,9 @@
             completeTask()
         case .failWithError(let errorCode):
             internalState = .transferFailed
-            failWith(errorCode: errorCode, request: request)
+            let error = NSError(domain: NSURLErrorDomain, code: errorCode,
+                                userInfo: [NSLocalizedDescriptionKey: "Completion failure"])
+            failWith(error: error, request: request)
         case .redirectWithRequest(let newRequest):
             redirectFor(request: newRequest)
         }
diff --git a/Foundation/URLSession/http/MultiHandle.swift b/Foundation/URLSession/http/MultiHandle.swift
index 506c9a9..4998899 100644
--- a/Foundation/URLSession/http/MultiHandle.swift
+++ b/Foundation/URLSession/http/MultiHandle.swift
@@ -202,12 +202,20 @@
         }
         let easyHandle = easyHandles[idx]
         // Find the NSURLError code
-        let errorCode = easyHandle.urlErrorCode(for: easyCode)
-        completedTransfer(forEasyHandle: easyHandle, errorCode: errorCode)
+        var error: NSError?
+        if let errorCode = easyHandle.urlErrorCode(for: easyCode) {
+            let errorDescription = easyHandle.errorBuffer[0] != 0 ?
+                String(cString: easyHandle.errorBuffer) :
+                CFURLSessionCreateErrorDescription(easyCode.value)._swiftObject
+            error = NSError(domain: NSURLErrorDomain, code: errorCode, userInfo: [
+                NSLocalizedDescriptionKey: errorDescription
+            ])
+        }
+        completedTransfer(forEasyHandle: easyHandle, error: error)
     }
     /// Transfer completed.
-    func completedTransfer(forEasyHandle handle: _EasyHandle, errorCode: Int?) {
-        handle.completedTransfer(withErrorCode: errorCode)
+    func completedTransfer(forEasyHandle handle: _EasyHandle, error: NSError?) {
+        handle.completedTransfer(withError: error)
     }
 }
 
diff --git a/Foundation/Unit.swift b/Foundation/Unit.swift
index f43e5ff..b27409c 100644
--- a/Foundation/Unit.swift
+++ b/Foundation/Unit.swift
@@ -1632,8 +1632,8 @@
         static let milliwatts = "mW"
         static let microwatts = "µW"
         static let nanowatts  = "nW"
-        static let picowatts  = "nW"
-        static let femtowatts = "nHz"
+        static let picowatts  = "pW"
+        static let femtowatts = "fW"
         static let horsepower = "hp"
     }
     
diff --git a/Foundation/UserDefaults.swift b/Foundation/UserDefaults.swift
index 42cbd0d..a1eba75 100644
--- a/Foundation/UserDefaults.swift
+++ b/Foundation/UserDefaults.swift
@@ -247,7 +247,7 @@
         set(NSNumber(value: value), forKey: defaultName)
     }
     open func set(_ url: URL?, forKey defaultName: String) {
-		if let url = url {
+        if let url = url {
             //FIXME: CFURLIsFileReferenceURL is limited to OS X/iOS
             #if os(OSX) || os(iOS)
                 //FIXME: no SwiftFoundation version of CFURLIsFileReferenceURL at time of writing!
diff --git a/TestFoundation/HTTPServer.swift b/TestFoundation/HTTPServer.swift
index ec2055f..4caab62 100644
--- a/TestFoundation/HTTPServer.swift
+++ b/TestFoundation/HTTPServer.swift
@@ -70,7 +70,7 @@
     public private(set) var port: UInt16
 
     init(port: UInt16?) throws {
-        #if os(Linux)
+        #if os(Linux) && !os(Android)
             let SOCKSTREAM = Int32(SOCK_STREAM.rawValue)
         #else
             let SOCKSTREAM = SOCK_STREAM
@@ -102,7 +102,9 @@
         // 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)
+        #if os(Android)
+            return sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: netPort, sin_addr: in_addr(s_addr: addr), __pad: (0,0,0,0,0,0,0,0))
+        #elseif os(Linux)
             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: netPort, sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
diff --git a/TestFoundation/TestAffineTransform.swift b/TestFoundation/TestAffineTransform.swift
index 9a897ad..15480e0 100644
--- a/TestFoundation/TestAffineTransform.swift
+++ b/TestFoundation/TestAffineTransform.swift
@@ -197,14 +197,14 @@
     func test_Inversion() {
         let point = NSPoint(x: CGFloat(10.0), y: CGFloat(10.0))
         
-        let translate = NSAffineTransform()
-        translate.translateX(by: CGFloat(-30.0), yBy: CGFloat(40.0))
+        var translate = AffineTransform()
+        translate.translate(x: CGFloat(-30.0), y: CGFloat(40.0))
         
-        let rotate = NSAffineTransform()
+        var rotate = AffineTransform()
         translate.rotate(byDegrees: CGFloat(30.0))
         
-        let scale = NSAffineTransform()
-        scale.scale(by: CGFloat(2.0))
+        var scale = AffineTransform()
+        scale.scale(CGFloat(2.0))
         
         let identityTransform = NSAffineTransform()
         
@@ -270,15 +270,15 @@
     func test_AppendTransform() {
         let point = NSPoint(x: CGFloat(10.0), y: CGFloat(10.0))
         
-        let identityTransform = NSAffineTransform()
+        var identityTransform = AffineTransform()
         identityTransform.append(identityTransform)
-        checkPointTransformation(identityTransform, point: point, expectedPoint: point)
+        checkPointTransformation(NSAffineTransform(transform: identityTransform), point: point, expectedPoint: point)
         
-        let translate = NSAffineTransform()
-        translate.translateX(by: CGFloat(10.0), yBy: CGFloat())
+        var translate = AffineTransform()
+        translate.translate(x: CGFloat(10.0), y: CGFloat())
         
-        let scale = NSAffineTransform()
-        scale.scale(by: CGFloat(2.0))
+        var scale = AffineTransform()
+        scale.scale(CGFloat(2.0))
         
         let translateThenScale = NSAffineTransform(transform: translate)
         translateThenScale.append(scale)
@@ -288,15 +288,15 @@
     func test_PrependTransform() {
         let point = NSPoint(x: CGFloat(10.0), y: CGFloat(10.0))
         
-        let identityTransform = NSAffineTransform()
+        var identityTransform = AffineTransform()
         identityTransform.prepend(identityTransform)
-        checkPointTransformation(identityTransform, point: point, expectedPoint: point)
+        checkPointTransformation(NSAffineTransform(transform: identityTransform), point: point, expectedPoint: point)
         
-        let translate = NSAffineTransform()
-        translate.translateX(by: CGFloat(10.0), yBy: CGFloat())
+        var translate = AffineTransform()
+        translate.translate(x: CGFloat(10.0), y: CGFloat())
         
-        let scale = NSAffineTransform()
-        scale.scale(by: CGFloat(2.0))
+        var scale = AffineTransform()
+        scale.scale(CGFloat(2.0))
         
         let scaleThenTranslate = NSAffineTransform(transform: translate)
         scaleThenTranslate.prepend(scale)
@@ -313,13 +313,13 @@
         let rotate = NSAffineTransform()
         rotate.rotate(byDegrees: CGFloat(90.0))
         
-        let moveOrigin = NSAffineTransform()
-        moveOrigin.translateX(by: -center.x, yBy: -center.y)
+        var moveOrigin = AffineTransform()
+        moveOrigin.translate(x: -center.x, y: -center.y)
         
-        let moveBack = NSAffineTransform(transform: moveOrigin)
+        var moveBack = moveOrigin
         moveBack.invert()
         
-        let rotateAboutCenter = NSAffineTransform(transform: rotate)
+        let rotateAboutCenter = rotate
         rotateAboutCenter.prepend(moveOrigin)
         rotateAboutCenter.append(moveBack)
         
@@ -344,7 +344,7 @@
         ]
         for val in values {
             let ref = NSAffineTransform()
-            ref.transformStruct = val
+            ref.transformStruct = NSAffineTransformStruct(m11: val.m11, m12: val.m12, m21: val.m21, m22: val.m22, tX: val.tX, tY: val.tY)
             XCTAssertEqual(ref.hashValue, val.hashValue)
         }
     }
diff --git a/TestFoundation/TestCharacterSet.swift b/TestFoundation/TestCharacterSet.swift
index 18a8f03..d613db1 100644
--- a/TestFoundation/TestCharacterSet.swift
+++ b/TestFoundation/TestCharacterSet.swift
@@ -76,10 +76,10 @@
             ("test_InlineBuffer", test_InlineBuffer),
             ("test_Equatable", test_Equatable),
             // The following tests must remain disabled until SR-2509 is resolved.
-            // ("test_Subtracting", test_Subtracting),
-            // ("test_SubtractEmptySet", test_SubtractEmptySet),
-            // ("test_SubtractNonEmptySet", test_SubtractNonEmptySet),
-            // ("test_SymmetricDifference", test_SymmetricDifference),
+            ("test_Subtracting", test_Subtracting),
+            ("test_SubtractEmptySet", test_SubtractEmptySet),
+            ("test_SubtractNonEmptySet", test_SubtractNonEmptySet),
+            ("test_SymmetricDifference", test_SymmetricDifference),
         ]
     }
     
diff --git a/TestFoundation/TestCodable.swift b/TestFoundation/TestCodable.swift
index f1fb7d6..d616a95 100644
--- a/TestFoundation/TestCodable.swift
+++ b/TestFoundation/TestCodable.swift
@@ -307,6 +307,7 @@
 
     // MARK: - TimeZone
     lazy var timeZoneValues: [TimeZone] = {
+#if !os(Android)
         var values = [
             TimeZone(identifier: "America/Los_Angeles")!,
             TimeZone(identifier: "UTC")!,
@@ -318,7 +319,12 @@
             // causing encode -> decode -> compare test to fail.
             values.append(TimeZone.current)
         #endif
-        
+#else
+        var values = [
+            TimeZone(identifier: "UTC")!,
+            TimeZone.current
+            ]
+#endif
         return values
     }()
 
diff --git a/TestFoundation/TestDecimal.swift b/TestFoundation/TestDecimal.swift
index f34d9f7..1fe51a8 100644
--- a/TestFoundation/TestDecimal.swift
+++ b/TestFoundation/TestDecimal.swift
@@ -277,7 +277,7 @@
                 }
             }
         }
-        XCTAssertEqual(Decimal(186243*15673), Decimal(186243) * Decimal(15673))
+        XCTAssertEqual(Decimal(186243 * 15673 as Int64), Decimal(186243) * Decimal(15673))
     }
 
     func test_Misc() {
@@ -308,7 +308,9 @@
         XCTAssertFalse(Decimal.nan.isTotallyOrdered(belowOrEqualTo: Decimal(2.3)))
         XCTAssertTrue(Decimal(2) < Decimal(3))
         XCTAssertTrue(Decimal(3) > Decimal(2))
+#if !arch(arm)
         XCTAssertEqual(3275573729074, Decimal(1234).hashValue)
+#endif
         XCTAssertEqual(Decimal(-9), Decimal(1) - Decimal(10))
         XCTAssertEqual(Decimal(3), Decimal(2).nextUp)
         XCTAssertEqual(Decimal(2), Decimal(3).nextDown)
diff --git a/TestFoundation/TestFileManager.swift b/TestFoundation/TestFileManager.swift
index 90d1597..bef3d27 100644
--- a/TestFoundation/TestFileManager.swift
+++ b/TestFoundation/TestFileManager.swift
@@ -24,6 +24,7 @@
             ("test_moveFile", test_moveFile),
             ("test_fileSystemRepresentation", test_fileSystemRepresentation),
             ("test_fileAttributes", test_fileAttributes),
+            ("test_fileSystemAttributes", test_fileSystemAttributes),
             ("test_setFileAttributes", test_setFileAttributes),
             ("test_directoryEnumerator", test_directoryEnumerator),
             ("test_pathEnumerator",test_pathEnumerator),
@@ -206,6 +207,40 @@
         }
     }
     
+    func test_fileSystemAttributes() {
+        let fm = FileManager.default
+        let path = NSTemporaryDirectory()
+        
+        do {
+            let attrs = try fm.attributesOfFileSystem(forPath: path)
+            
+            XCTAssertTrue(attrs.count > 0)
+            
+            let systemNumber = attrs[.systemNumber] as? NSNumber
+            XCTAssertNotNil(systemNumber)
+            XCTAssertNotEqual(systemNumber!.uint64Value, 0)
+            
+            let systemFreeSize = attrs[.systemFreeSize] as? NSNumber
+            XCTAssertNotNil(systemFreeSize)
+            XCTAssertNotEqual(systemFreeSize!.uint64Value, 0)
+            
+            let systemSize = attrs[.systemSize] as? NSNumber
+            XCTAssertNotNil(systemSize)
+            XCTAssertGreaterThan(systemSize!.uint64Value, systemFreeSize!.uint64Value)
+            
+            let systemFreeNodes = attrs[.systemFreeNodes] as? NSNumber
+            XCTAssertNotNil(systemFreeNodes)
+            XCTAssertNotEqual(systemFreeNodes!.uint64Value, 0)
+            
+            let systemNodes = attrs[.systemNodes] as? NSNumber
+            XCTAssertNotNil(systemNodes)
+            XCTAssertGreaterThan(systemNodes!.uint64Value, systemFreeNodes!.uint64Value)
+            
+        } catch let err {
+            XCTFail("\(err)")
+        }
+    }
+    
     func test_setFileAttributes() {
         let path = NSTemporaryDirectory() + "test_setFileAttributes\(NSUUID().uuidString)"
         let fm = FileManager.default
diff --git a/TestFoundation/TestHTTPCookieStorage.swift b/TestFoundation/TestHTTPCookieStorage.swift
index f65a01e..757f64b 100644
--- a/TestFoundation/TestHTTPCookieStorage.swift
+++ b/TestFoundation/TestHTTPCookieStorage.swift
@@ -239,6 +239,7 @@
     }
 
     func test_cookieInXDGSpecPath() {
+#if !os(Android)
         //Test without setting the environment variable
         let testCookie = HTTPCookie(properties: [
            .name: "TestCookie0",
@@ -287,5 +288,6 @@
         let terminationReason = task.terminationReason
         XCTAssertEqual(terminationReason, Process.TerminationReason.exit)
         try? fm.removeItem(atPath: testPath)
+#endif
     }
 }
diff --git a/TestFoundation/TestISO8601DateFormatter.swift b/TestFoundation/TestISO8601DateFormatter.swift
index 2173a22..5806ddb 100644
--- a/TestFoundation/TestISO8601DateFormatter.swift
+++ b/TestFoundation/TestISO8601DateFormatter.swift
@@ -100,6 +100,7 @@
         isoFormatter.formatOptions = [.withMonth, .withDay, .withWeekOfYear, .withDashSeparatorInDate]
         XCTAssertEqual(isoFormatter.string(from: someDateTime!), "10-W40-06")
 
+#if !os(Android)
         /*
          The following tests cover various cases when changing the .formatOptions property with a different TimeZone set.
          */
@@ -141,7 +142,7 @@
 
         isoFormatter.formatOptions = [.withDay, .withWeekOfYear, .withMonth, .withTimeZone, .withColonSeparatorInTimeZone, .withDashSeparatorInDate]
         XCTAssertEqual(isoFormatter.string(from: someDateTime!), "10-W40-06-07:00")
-        
+#endif
     }
     
     
@@ -248,6 +249,7 @@
         formatOptions = [.withMonth, .withDay, .withWeekOfYear, .withDashSeparatorInDate]
         XCTAssertEqual(ISO8601DateFormatter.string(from: someDateTime!, timeZone: timeZone!, formatOptions: formatOptions), "10-W40-06")
 
+#if !os(Android)
         /*
          The following tests cover various cases when changing the .formatOptions property with a different TimeZone set.
          */
@@ -289,7 +291,7 @@
 
         formatOptions = [.withDay, .withWeekOfYear, .withMonth, .withTimeZone, .withColonSeparatorInTimeZone, .withDashSeparatorInDate]
         XCTAssertEqual(ISO8601DateFormatter.string(from: someDateTime!, timeZone: timeZone!, formatOptions: formatOptions), "10-W40-06-07:00")
-  
+#endif
     }
 
 }
diff --git a/TestFoundation/TestJSONEncoder.swift b/TestFoundation/TestJSONEncoder.swift
index 76dc81a..cfb2011 100644
--- a/TestFoundation/TestJSONEncoder.swift
+++ b/TestFoundation/TestJSONEncoder.swift
@@ -354,11 +354,15 @@
     }
 
     func test_codingOfInt64() {
+#if !arch(arm)
         test_codingOf(value: Int64(-9000000000000000042), toAndFrom: "-9000000000000000042")
+#endif
     }
 
     func test_codingOfUInt64() {
+#if !arch(arm)
         test_codingOf(value: UInt64(9000000000000000042), toAndFrom: "9000000000000000042")
+#endif
     }
 
     func test_codingOfInt() {
@@ -367,7 +371,11 @@
         case 4: // 32-bit
             test_codingOf(value: Int(-2000000042), toAndFrom: "-2000000042")
         case 8: // 64-bit
+#if arch(arm)
+            break
+#else
             test_codingOf(value: Int(-9000000000000000042), toAndFrom: "-9000000000000000042")
+#endif
         default:
             XCTFail("Unexpected UInt size: \(intSize)")
         }
@@ -379,7 +387,11 @@
         case 4: // 32-bit
             test_codingOf(value: UInt(2000000042), toAndFrom: "2000000042")
         case 8: // 64-bit
+#if arch(arm)
+            break
+#else
             test_codingOf(value: UInt(9000000000000000042), toAndFrom: "9000000000000000042")
+#endif
         default:
             XCTFail("Unexpected UInt size: \(uintSize)")
         }
diff --git a/TestFoundation/TestNSArray.swift b/TestFoundation/TestNSArray.swift
index 8442ecd..4ea6818 100644
--- a/TestFoundation/TestNSArray.swift
+++ b/TestFoundation/TestNSArray.swift
@@ -24,13 +24,15 @@
     static var allTests: [(String, (TestNSArray) -> () throws -> Void)] {
         return [
             ("test_BasicConstruction", test_BasicConstruction),
+            ("test_constructors", test_constructors),
+            ("test_constructorWithCopyItems", test_constructorWithCopyItems),
             ("test_enumeration", test_enumeration),
             ("test_sequenceType", test_sequenceType),
             ("test_objectAtIndex", test_objectAtIndex),
             ("test_binarySearch", test_binarySearch),
             ("test_binarySearchFringeCases", test_binarySearchFringeCases),
-            ("test_replaceObjectsInRange_withObjectsFromArray", test_replaceObjectsInRange_withObjectsFromArray),
-            ("test_replaceObjectsInRange_withObjectsFromArray_range", test_replaceObjectsInRange_withObjectsFromArray_range),
+            ("test_replaceObjectsInRange_withObjectsFrom", test_replaceObjectsInRange_withObjectsFrom),
+            ("test_replaceObjectsInRange_withObjectsFrom_range", test_replaceObjectsInRange_withObjectsFrom_range),
             ("test_replaceObjectAtIndex", test_replaceObjectAtIndex),
             ("test_removeObjectsInArray", test_removeObjectsInArray),
             ("test_sortedArrayUsingComparator", test_sortedArrayUsingComparator),
@@ -43,7 +45,8 @@
             ("test_copying", test_copying),
             ("test_mutableCopying", test_mutableCopying),
             ("test_writeToFile", test_writeToFile),
-            ("test_initWithContentsOfFile", test_initWithContentsOfFile)
+            ("test_initWithContentsOfFile", test_initWithContentsOfFile),
+            ("test_readWriteURL", test_readWriteURL)
         ]
     }
     
@@ -53,6 +56,47 @@
         XCTAssertEqual(array.count, 0)
         XCTAssertEqual(array2.count, 2)
     }
+
+    func test_constructors() {
+        let arrayNil = NSArray(objects: nil, count: 0)
+        XCTAssertEqual(arrayNil.count, 0)
+
+        let array1 = NSArray(object: "foo")
+        XCTAssertEqual(array1.count, 1)
+
+        let testStrings: [AnyObject] = [NSString(string:"foo"), NSString(string: "bar")]
+        testStrings.withUnsafeBufferPointer { ptr in
+            let array2 = NSArray(objects: ptr.baseAddress, count: 1)
+            XCTAssertEqual(array1, array2)
+        }
+
+        let array3 = NSArray(objects: "foo" as NSString, "bar" as NSString, "baz" as NSString)
+        XCTAssertEqual(array3.count, 3)
+        let array4 = NSArray(array: ["foo", "bar", "baz"])
+        XCTAssertEqual(array4.count, 3)
+        let array5 = NSArray(arrayLiteral: "foo", "bar", "baz")
+        XCTAssertEqual(array5.count, 3)
+        XCTAssertEqual(array3, array4)
+        XCTAssertEqual(array3, array5)
+        XCTAssertEqual(array4, array5)
+
+    }
+
+    func test_constructorWithCopyItems() {
+        let foo = "foo" as NSMutableString
+
+        let array1 = NSArray(array: [foo], copyItems: false)
+        let array2 = NSArray(array: [foo], copyItems: true)
+
+        XCTAssertEqual(array1[0] as! String, "foo")
+        XCTAssertEqual(array2[0] as! String, "foo")
+
+        // Disable this test for now as it fails, althought it works against Darwin Foundation.
+        // The test may not acutally be correct anyway.
+        //foo.append("1")
+        //XCTAssertEqual(array1[0] as! String, "foo1")
+        //XCTAssertEqual(array2[0] as! String, "foo")
+    }
     
     func test_enumeration() {
         let array : NSArray = ["foo", "bar", "baz"]
@@ -174,7 +218,7 @@
             NSNumber(value: 0 as Int), NSNumber(value: 1 as Int), NSNumber(value: 2 as Int), NSNumber(value: 3 as Int),
             NSNumber(value: 4 as Int), NSNumber(value: 5 as Int), NSNumber(value: 7 as Int)]
         let array = NSMutableArray(array: numbers)
-        array.replaceObjects(in: NSRange(location: 0, length: 2), withObjectsFromArray: [NSNumber(value: 8 as Int), NSNumber(value: 9 as Int)])
+        array.replaceObjects(in: NSRange(location: 0, length: 2), withObjectsFrom: [NSNumber(value: 8 as Int), NSNumber(value: 9 as Int)])
         XCTAssertTrue((array[0] as! NSNumber).intValue == 8)
         XCTAssertTrue((array[1] as! NSNumber).intValue == 9)
         XCTAssertTrue((array[2] as! NSNumber).intValue == 2)
@@ -278,7 +322,7 @@
         return .orderedDescending
     }
     
-    func test_replaceObjectsInRange_withObjectsFromArray() {
+    func test_replaceObjectsInRange_withObjectsFrom() {
         let array1 = NSMutableArray(array:[
             "foo1",
             "bar1",
@@ -289,7 +333,7 @@
             "bar2",
             "baz2"]
         
-        array1.replaceObjects(in: NSMakeRange(0, 2), withObjectsFromArray: array2)
+        array1.replaceObjects(in: NSMakeRange(0, 2), withObjectsFrom: array2)
         
         XCTAssertEqual(array1[0] as? String, "foo2", "Expected foo2 but was \(array1[0])")
         XCTAssertEqual(array1[1] as? String, "bar2", "Expected bar2 but was \(array1[1])")
@@ -297,7 +341,7 @@
         XCTAssertEqual(array1[3] as? String, "baz1", "Expected baz1 but was \(array1[3])")
     }
     
-    func test_replaceObjectsInRange_withObjectsFromArray_range() {
+    func test_replaceObjectsInRange_withObjectsFrom_range() {
         let array1 = NSMutableArray(array:[
             "foo1",
             "bar1",
@@ -337,7 +381,7 @@
         let resultNumbers = NSArray(array: inputNumbers).sortedArray(comparator:) { left, right -> ComparisonResult in
             let l = (left as! NSNumber).intValue
             let r = (right as! NSNumber).intValue
-            return l < r ? .orderedAscending : (l > r ? .orderedSame : .orderedDescending)
+            return l < r ? .orderedAscending : (l == r ? .orderedSame : .orderedDescending)
         }
         XCTAssertEqual(resultNumbers.map { ($0 as! NSNumber).intValue}, expectedNumbers)
     }
@@ -368,7 +412,7 @@
         func compare(_ left: Any, right:Any,  context: UnsafeMutableRawPointer?) -> Int {
             let l = (left as! NSNumber).intValue
             let r = (right as! NSNumber).intValue
-            return l < r ? -1 : (l > r ? 0 : 1)
+            return l < r ? -1 : (l == r ? 0 : 1)
         }
         mutableInput.sort(compare, context: UnsafeMutableRawPointer(bitPattern: 0))
 
@@ -384,7 +428,7 @@
         mutableInput.sort { left, right -> ComparisonResult in
             let l = (left as! NSNumber).intValue
             let r = (right as! NSNumber).intValue
-            return l < r ? .orderedAscending : (l > r ? .orderedSame : .orderedDescending)
+            return l < r ? .orderedAscending : (l == r ? .orderedSame : .orderedDescending)
         }
 
         XCTAssertEqual(mutableInput.map { ($0 as! NSNumber).intValue}, expectedNumbers)
@@ -398,7 +442,7 @@
             let r = right as! String
             return l.localizedCaseInsensitiveCompare(r)
         }
-        mutableStringsInput1.sort(comparator)
+        mutableStringsInput1.sort(comparator: comparator)
         mutableStringsInput2.sort(options: [], usingComparator: comparator)
         XCTAssertTrue(mutableStringsInput1.isEqual(to: Array(mutableStringsInput2)))
     }
@@ -464,7 +508,7 @@
         }
     }
 
-        func test_initWithContentsOfFile() {
+    func test_initWithContentsOfFile() {
         let testFilePath = createTestFile("TestFileOut.txt", _contents: Data(capacity: 234))
         if let _ = testFilePath {
             let a1: NSArray = ["foo", "bar"]
@@ -504,7 +548,23 @@
             XCTFail("Temporary file creation failed")
         }
     }
-    
+
+    func test_readWriteURL() {
+        let data = NSArray(arrayLiteral: "one", "two", "three", "four", "five")
+        do {
+            let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString
+            try FileManager.default.createDirectory(atPath: tempDir, withIntermediateDirectories: false, attributes: nil)
+            let testFile = tempDir + "/readWriteURL.txt"
+            let url = URL(fileURLWithPath: testFile)
+            try data.write(to: url)
+            let data2 = try NSArray(contentsOf: url, error: ())
+            XCTAssertEqual(data, data2)
+            removeTestFile(testFile)
+        } catch let e {
+            XCTFail("Failed to write to file: \(e)")
+        }
+    }
+
     private func createTestFile(_ path: String, _contents: Data) -> String? {
         let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
         do {
diff --git a/TestFoundation/TestNSAttributedString.swift b/TestFoundation/TestNSAttributedString.swift
index edeb6d1..5b08922 100644
--- a/TestFoundation/TestNSAttributedString.swift
+++ b/TestFoundation/TestNSAttributedString.swift
@@ -18,7 +18,6 @@
 #endif
 
 
-
 class TestNSAttributedString : XCTestCase {
     
     static var allTests: [(String, (TestNSAttributedString) -> () throws -> Void)] {
@@ -30,7 +29,7 @@
             ("test_enumerateAttributes", test_enumerateAttributes),
         ]
     }
-    
+
     func test_initWithString() {
         let string = "Lorem 😀 ipsum dolor sit amet, consectetur adipiscing elit. ⌘ Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit. ಠ_ರೃ"
         let attrString = NSAttributedString(string: string)
@@ -43,7 +42,7 @@
         XCTAssertEqual(range.length, string.utf16.count)
         XCTAssertEqual(attrs.count, 0)
 
-        let attribute = attrString.attribute("invalid", at: 0, effectiveRange: &range)
+        let attribute = attrString.attribute(NSAttributedStringKey("invalid"), at: 0, effectiveRange: &range)
         XCTAssertNil(attribute)
         XCTAssertEqual(range.location, 0)
         XCTAssertEqual(range.length, string.utf16.count)
@@ -51,7 +50,7 @@
     
     func test_initWithStringAndAttributes() {
         let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
-        let attributes: [String : AnyObject] = ["attribute.placeholder.key" : "attribute.placeholder.value" as NSString]
+        let attributes: [NSAttributedStringKey : AnyObject] = [NSAttributedStringKey("attribute.placeholder.key") : "attribute.placeholder.value" as NSString]
         
         let attrString = NSAttributedString(string: string, attributes: attributes)
         XCTAssertEqual(attrString.string, string)
@@ -59,7 +58,7 @@
         
         var range = NSRange()
         let attrs = attrString.attributes(at: 0, effectiveRange: &range)
-        guard let value = attrs["attribute.placeholder.key"] as? String else {
+        guard let value = attrs[NSAttributedStringKey("attribute.placeholder.key")] as? String else {
             XCTAssert(false, "attribute value not found")
             return
         }
@@ -67,16 +66,16 @@
         XCTAssertEqual(range.length, attrString.length)
         XCTAssertEqual(value, "attribute.placeholder.value")
 
-        let invalidAttribute = attrString.attribute("invalid", at: 0, effectiveRange: &range)
+        let invalidAttribute = attrString.attribute(NSAttributedStringKey("invalid"), at: 0, effectiveRange: &range)
         XCTAssertNil(invalidAttribute)
         XCTAssertEqual(range.location, 0)
         XCTAssertEqual(range.length, string.utf16.count)
 
-        let attribute = attrString.attribute("attribute.placeholder.key", at: 0, effectiveRange: &range)
+        let attribute = attrString.attribute(NSAttributedStringKey("attribute.placeholder.key"), at: 0, effectiveRange: &range)
         XCTAssertEqual(range.location, 0)
         XCTAssertEqual(range.length, attrString.length)
         guard let validAttribute = attribute as? NSString else {
-            XCTAssert(false, "attribuet not found")
+            XCTAssert(false, "attribute not found")
             return
         }
         XCTAssertEqual(validAttribute, "attribute.placeholder.value")
@@ -85,7 +84,7 @@
     func test_longestEffectiveRange() {
         let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
         
-        let attrKey = "attribute.placeholder.key"
+        let attrKey = NSAttributedStringKey("attribute.placeholder.key")
         let attrValue = "attribute.placeholder.value" as NSString
         
         let attrRange1 = NSRange(location: 0, length: 20)
@@ -110,12 +109,12 @@
     func test_enumerateAttributeWithName() {
         let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
         
-        let attrKey1 = "attribute.placeholder.key1"
+        let attrKey1 = NSAttributedStringKey("attribute.placeholder.key1")
         let attrValue1 = "attribute.placeholder.value1"
         let attrRange1 = NSRange(location: 0, length: 20)
         let attrRange2 = NSRange(location: 18, length: 10)
         
-        let attrKey3 = "attribute.placeholder.key3"
+        let attrKey3 = NSAttributedStringKey("attribute.placeholder.key3")
         let attrValue3 = "attribute.placeholder.value3"
         let attrRange3 = NSRange(location: 40, length: 5)
         
@@ -155,17 +154,21 @@
     }
     
     func test_enumerateAttributes() {
+#if os(Android)
+        // Invalid dictionary returned by CFAttributedStringGetAttributesAndLongestEffectiveRange
+        XCTFail("Intermittent failures on Android")
+#else
         let string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur et sem vitae consectetur. Nam venenatis lectus a laoreet blandit."
         
-        let attrKey1 = "attribute.placeholder.key1"
+        let attrKey1 = NSAttributedStringKey("attribute.placeholder.key1")
         let attrValue1 = "attribute.placeholder.value1"
         let attrRange1 = NSRange(location: 0, length: 20)
         
-        let attrKey2 = "attribute.placeholder.key2"
+        let attrKey2 = NSAttributedStringKey("attribute.placeholder.key2")
         let attrValue2 = "attribute.placeholder.value2"
         let attrRange2 = NSRange(location: 18, length: 10)
         
-        let attrKey3 = "attribute.placeholder.key3"
+        let attrKey3 = NSAttributedStringKey("attribute.placeholder.key3")
         let attrValue3 = "attribute.placeholder.value3"
         let attrRange3 = NSRange(location: 40, length: 5)
         
@@ -213,6 +216,7 @@
         }
         XCTAssertEqual(rangeDescriptionString, "(0,10)")
         XCTAssertEqual(attrsDescriptionString, "[attribute.placeholder.key1:attribute.placeholder.value1]")
+#endif
     }
 }
 
@@ -230,9 +234,9 @@
         }
     }
     
-    fileprivate func describe(attrs: [String : Any]) -> String {
+    fileprivate func describe(attrs: [NSAttributedStringKey : Any]) -> String {
         if attrs.count > 0 {
-            return "[" + attrs.map({ "\($0):\($1)" }).sorted(by: { $0 < $1 }).joined(separator: ",") + "]"
+            return "[" + attrs.map({ "\($0.rawValue):\($1)" }).sorted(by: { $0 < $1 }).joined(separator: ",") + "]"
         } else {
             return "[:]"
         }
diff --git a/TestFoundation/TestNSData.swift b/TestFoundation/TestNSData.swift
index 3bacd6e..db88d57 100644
--- a/TestFoundation/TestNSData.swift
+++ b/TestFoundation/TestNSData.swift
@@ -205,16 +205,16 @@
             ("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
+            ("test_dataHash", test_dataHash),
             ("test_genericBuffers", test_genericBuffers),
-            // ("test_writeFailure", test_writeFailure), segfaults
+            ("test_writeFailure", test_writeFailure),
             ("testBasicConstruction", testBasicConstruction),
             ("testBridgingDefault", testBridgingDefault),
             ("testBridgingMutable", testBridgingMutable),
             ("testCopyBytes_oversized", testCopyBytes_oversized),
             ("testCopyBytes_ranges", testCopyBytes_ranges),
             ("testCopyBytes_undersized", testCopyBytes_undersized),
-             ("testCopyBytes", testCopyBytes),
+            ("testCopyBytes", testCopyBytes),
             ("testCustomDeallocator", testCustomDeallocator),
             ("testDataInSet", testDataInSet),
             ("testEquality", testEquality),
@@ -229,8 +229,7 @@
             ("testReplaceSubrange3", testReplaceSubrange3),
             ("testReplaceSubrange4", testReplaceSubrange4),
             ("testReplaceSubrange5", testReplaceSubrange5),
-            
-            
+
             ("test_description", test_description),
             ("test_emptyDescription", test_emptyDescription),
             ("test_longDescription", test_longDescription),
@@ -259,7 +258,7 @@
             ("test_initDataWithCount", test_initDataWithCount),
             ("test_emptyStringToData", test_emptyStringToData),
             ("test_repeatingValueInitialization", test_repeatingValueInitialization),
-            
+
             ("test_sliceAppending", test_sliceAppending),
             ("test_replaceSubrange", test_replaceSubrange),
             ("test_sliceWithUnsafeBytes", test_sliceWithUnsafeBytes),
@@ -508,12 +507,14 @@
             ("test_sliceHash", test_sliceHash),
             ("test_slice_resize_growth", test_slice_resize_growth),
 //            ("test_sliceEnumeration", test_sliceEnumeration),
+            ("test_sliceInsertion", test_sliceInsertion),
+            ("test_sliceDeletion", test_sliceDeletion),
         ]
     }
     
     func test_writeToURLOptions() {
         let saveData = try! Data(contentsOf: Bundle.main.url(forResource: "Test", withExtension: "plist")!)
-        let savePath = URL(fileURLWithPath: "/var/tmp/Test.plist")
+        let savePath = URL(fileURLWithPath: NSTemporaryDirectory() + "Test1.plist")
         do {
             try saveData.write(to: savePath, options: .atomic)
             let fileManager = FileManager.default
@@ -3952,5 +3953,31 @@
         XCTAssertEqual(Data(bytes: [0]), regionData[2]) //fails
     }
  */
+    
+    func test_sliceInsertion() {
+        // https://bugs.swift.org/browse/SR-5810
+        let baseData = Data([0, 1, 2, 3, 4, 5])
+        var sliceData = baseData[2..<4]
+        let sliceDataEndIndexBeforeInsertion = sliceData.endIndex
+        let elementToInsert: UInt8 = 0x07
+        sliceData.insert(elementToInsert, at: sliceData.startIndex)
+        XCTAssertEqual(sliceData.first, elementToInsert)
+        XCTAssertEqual(sliceData.startIndex, 2)
+        XCTAssertEqual(sliceDataEndIndexBeforeInsertion, 4)
+        XCTAssertEqual(sliceData.endIndex, sliceDataEndIndexBeforeInsertion + 1)
+    }
+    
+    func test_sliceDeletion() {
+        // https://bugs.swift.org/browse/SR-5810
+        let baseData = Data([0, 1, 2, 3, 4, 5, 6, 7])
+        let sliceData = baseData[2..<6]
+        var mutableSliceData = sliceData
+        let numberOfElementsToDelete = 2
+        let subrangeToDelete = mutableSliceData.startIndex..<mutableSliceData.startIndex.advanced(by: numberOfElementsToDelete)
+        mutableSliceData.removeSubrange(subrangeToDelete)
+        XCTAssertEqual(sliceData[sliceData.startIndex + numberOfElementsToDelete], mutableSliceData.first)
+        XCTAssertEqual(mutableSliceData.startIndex, 2)
+        XCTAssertEqual(mutableSliceData.endIndex, sliceData.endIndex - numberOfElementsToDelete)
+    }
 }
 
diff --git a/TestFoundation/TestNSDictionary.swift b/TestFoundation/TestNSDictionary.swift
index fa09cb0..b1435d4 100644
--- a/TestFoundation/TestNSDictionary.swift
+++ b/TestFoundation/TestNSDictionary.swift
@@ -24,7 +24,7 @@
     static var allTests: [(String, (TestNSDictionary) -> () throws -> Void)] {
         return [
             ("test_BasicConstruction", test_BasicConstruction),
-//            ("test_ArrayConstruction", test_ArrayConstruction),
+            ("test_ArrayConstruction", test_ArrayConstruction),
             ("test_description", test_description),
             ("test_enumeration", test_enumeration),
             ("test_equality", test_equality),
@@ -60,12 +60,12 @@
         XCTAssertEqual(dict2[1] as? NSNumber, NSNumber(value: 2))
     }
     
-//    func test_ArrayConstruction() {
-//        let objects = ["foo", "bar", "baz"]
-//        let keys = ["foo", "bar", "baz"]
-//        let dict = NSDictionary(objects: objects, forKeys: keys)
-//        XCTAssertEqual(dict.count, 3)
-//    }
+    func test_ArrayConstruction() {
+        let objects = ["foo", "bar", "baz"]
+        let keys: [NSString] = ["foo", "bar", "baz"]
+        let dict = NSDictionary(objects: objects, forKeys: keys)
+        XCTAssertEqual(dict.count, 3)
+    }
     
     func test_enumeration() {
         let dict : NSDictionary = ["foo" : "bar", "whiz" : "bang", "toil" : "trouble"]
diff --git a/TestFoundation/TestNSLocale.swift b/TestFoundation/TestNSLocale.swift
index 3f9a48e..11398ef 100644
--- a/TestFoundation/TestNSLocale.swift
+++ b/TestFoundation/TestNSLocale.swift
@@ -115,12 +115,16 @@
     }
  
     func test_localeProperties(){
+#if os(Android)
+        XCTFail("Locale lookup unavailable on Android")
+#else
         let enUSID = "en_US"
         let locale = Locale(identifier: enUSID)
         XCTAssertEqual(String(describing: locale.languageCode!), "en")
         XCTAssertEqual(String(describing: locale.decimalSeparator!), ".")
         XCTAssertEqual(String(describing: locale.currencyCode!), "USD")
         XCTAssertEqual(String(describing: locale.collatorIdentifier!), enUSID)
+#endif
     }
 
 }
diff --git a/TestFoundation/TestNSLock.swift b/TestFoundation/TestNSLock.swift
new file mode 100644
index 0000000..06562b3
--- /dev/null
+++ b/TestFoundation/TestNSLock.swift
@@ -0,0 +1,128 @@
+// 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
+
+import CoreFoundation
+
+class TestNSLock: XCTestCase {
+    static var allTests: [(String, (TestNSLock) -> () throws -> Void)] {
+        return [
+
+            ("test_lockWait", test_lockWait),
+            ("test_threadsAndLocks", test_threadsAndLocks),
+
+        ]
+    }
+
+
+    func test_lockWait() {
+        let condition = NSCondition()
+        let lock = NSLock()
+
+        func test(waitTime: CFTimeInterval, shouldLock: Bool) -> Bool {
+            let locked = lock.lock(before: Date.init(timeIntervalSinceNow: waitTime))
+            if locked {
+                lock.unlock()
+            }
+            return locked == shouldLock
+        }
+
+        let thread = Thread() {
+            lock.lock()
+
+            // Now wake up the main thread so it can try to obtain the lock that
+            // this thread just obtained.
+            condition.lock()
+            condition.signal()
+            condition.unlock()
+
+            Thread.sleep(forTimeInterval: 8)
+            lock.unlock()
+        }
+        condition.lock()
+        thread.start()
+        condition.wait()
+        condition.unlock()
+
+        XCTAssertTrue(test(waitTime: 0, shouldLock: false))
+        XCTAssertTrue(test(waitTime: -1, shouldLock: false))
+        XCTAssertTrue(test(waitTime: 1, shouldLock: false))
+        XCTAssertTrue(test(waitTime: 4, shouldLock: false))
+        XCTAssertTrue(test(waitTime: 8, shouldLock: true))
+        XCTAssertTrue(test(waitTime: -1, shouldLock: true))
+    }
+
+
+    func test_threadsAndLocks() {
+        let condition = NSCondition()
+        let lock = NSLock()
+        let threadCount = 10
+        let endSeconds: Double = 2
+
+        let endTime = Date.init(timeIntervalSinceNow: endSeconds)
+        var threadsStarted = Array<Bool>(repeating: false, count: threadCount)
+        let arrayLock = NSLock()
+
+        for t in 0..<threadCount {
+            let thread = Thread() {
+                arrayLock.lock()
+                threadsStarted[t] = true
+                arrayLock.unlock()
+
+                condition.lock()
+                condition.wait()
+                condition.unlock()
+                for _ in 1...50 {
+                    let r = (endSeconds * drand48()) / 50
+                    Thread.sleep(forTimeInterval: r)
+                    if lock.lock(before: endTime) {
+                        lock.unlock()
+                    }
+                }
+                arrayLock.lock()
+                threadsStarted[t] = false
+                arrayLock.unlock()
+            }
+            thread.start()
+        }
+
+        var totalThreads = 0
+        repeat {
+            arrayLock.lock()
+            totalThreads = threadsStarted.filter {$0 == true }.count
+            arrayLock.unlock()
+        } while totalThreads < threadCount
+        XCTAssertEqual(totalThreads, threadCount)
+
+        condition.lock()
+        condition.broadcast()
+        condition.unlock()
+
+        Thread.sleep(until: endTime)
+        repeat {
+            arrayLock.lock()
+            totalThreads = threadsStarted.filter {$0 == false }.count
+            arrayLock.unlock()
+        } while totalThreads < threadCount
+        XCTAssertEqual(totalThreads, threadCount)
+
+        let gotLock = lock.try()
+        XCTAssertTrue(gotLock)
+        if gotLock {
+            lock.unlock()
+        }
+    }
+}
diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift
index 9d2ac9c..28a7b80 100644
--- a/TestFoundation/TestNSNumber.swift
+++ b/TestFoundation/TestNSNumber.swift
@@ -297,7 +297,12 @@
         let uintSize = MemoryLayout<UInt>.size
         switch uintSize {
         case 4: XCTAssertEqual(NSNumber(value: Int16.min).uintValue, 4294934528)
-        case 8: XCTAssertEqual(NSNumber(value: Int16.min).uintValue, 18446744073709518848)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int16.min).uintValue, 18446744073709518848)
+#endif
         default: XCTFail("Unexpected UInt size: \(uintSize)")
         }
 
@@ -402,7 +407,12 @@
         let uintSize = MemoryLayout<UInt>.size
         switch uintSize {
         case 4: XCTAssertEqual(NSNumber(value: Int32.min).uintValue, 2147483648)
-        case 8: XCTAssertEqual(NSNumber(value: Int32.min).uintValue, 18446744071562067968)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int32.min).uintValue, 18446744071562067968)
+#endif
         default: XCTFail("Unexpected UInt size: \(uintSize)")
         }
 
@@ -466,7 +476,12 @@
         let intSize = MemoryLayout<Int>.size
         switch intSize {
         case 4: XCTAssertEqual(NSNumber(value: UInt32.max).intValue, -1)
-        case 8: XCTAssertEqual(NSNumber(value: UInt32.max).intValue, 4294967295)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: UInt32.max).intValue, 4294967295)
+#endif
         default: XCTFail("Unexpected Int size: \(intSize)")
         }
         XCTAssertEqual(NSNumber(value: UInt32.max).uintValue, 4294967295)
@@ -511,14 +526,24 @@
         let intSize = MemoryLayout<Int>.size
         switch intSize {
         case 4: XCTAssertEqual(NSNumber(value: Int64.min).intValue, 0)
-        case 8: XCTAssertEqual(NSNumber(value: Int64.min).intValue, -9223372036854775808)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int64.min).intValue, -9223372036854775808)
+#endif
         default: XCTFail("Unexpected Int size: \(intSize)")
         }
 
         let uintSize = MemoryLayout<UInt>.size
         switch uintSize {
         case 4: XCTAssertEqual(NSNumber(value: Int64.min).uintValue, 0)
-        case 8: XCTAssertEqual(NSNumber(value: Int64.min).uintValue, 9223372036854775808)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int64.min).uintValue, 9223372036854775808)
+#endif
         default: XCTFail("Unexpected UInt size: \(uintSize)")
         }
 
@@ -541,13 +566,23 @@
 
         switch intSize {
         case 4: XCTAssertEqual(NSNumber(value: Int64.max).intValue, -1)
-        case 8: XCTAssertEqual(NSNumber(value: Int64.max).intValue, 9223372036854775807)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int64.max).intValue, 9223372036854775807)
+#endif
         default: XCTFail("Unexpected Int size: \(intSize)")
         }
 
         switch uintSize {
         case 4: XCTAssertEqual(NSNumber(value: Int64.max).uintValue, 4294967295)
-        case 8: XCTAssertEqual(NSNumber(value: Int64.max).uintValue, 9223372036854775807)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: Int64.max).uintValue, 9223372036854775807)
+#endif
         default: XCTFail("Unexpected UInt size: \(uintSize)")
         }
 
@@ -592,7 +627,12 @@
         let uintSize = MemoryLayout<UInt>.size
         switch uintSize {
         case 4: XCTAssertEqual(NSNumber(value: UInt64.max).uintValue, 4294967295)
-        case 8: XCTAssertEqual(NSNumber(value: UInt64.max).uintValue, 18446744073709551615)
+        case 8:
+#if arch(arm)
+                break
+#else
+                XCTAssertEqual(NSNumber(value: UInt64.max).uintValue, 18446744073709551615)
+#endif
         default: XCTFail("Unexpected UInt size: \(uintSize)")
         }
 
@@ -638,8 +678,9 @@
             XCTAssertEqual(NSNumber(value: Int.min).uint64Value, 18446744071562067968)
 
             XCTAssertEqual(NSNumber(value: Int.min).intValue, -2147483648)
+#if !arch(arm)
             XCTAssertEqual(NSNumber(value: Int.min).uintValue, 18446744071562067968)
-
+#endif
             XCTAssertEqual(NSNumber(value: Int.min).floatValue, Float(Int.min))
             XCTAssertEqual(NSNumber(value: Int.min).doubleValue, Double(Int.min))
 
@@ -664,6 +705,9 @@
             XCTAssertEqual(NSNumber(value: Int.max).doubleValue, Double(Int.max))
 
         case (8, 8):
+#if arch(arm)
+            break
+#else
             XCTAssertEqual(NSNumber(value: Int.min).boolValue, false)
 
             XCTAssertEqual(NSNumber(value: Int.min).int8Value, 0)
@@ -701,7 +745,7 @@
 
             XCTAssertEqual(NSNumber(value: Int.max).floatValue, Float(Int.max))
             XCTAssertEqual(NSNumber(value: Int.max).doubleValue, Double(Int.max))
-
+#endif
         default: XCTFail("Unexpected mismatched Int & UInt sizes: \(intSize) & \(uintSize)")
         }
     }
@@ -743,7 +787,9 @@
             XCTAssertEqual(NSNumber(value: UInt.max).uint32Value, 4294967295)
             XCTAssertEqual(NSNumber(value: UInt.max).uint64Value, 4294967295)
 
+#if !arch(arm)
             XCTAssertEqual(NSNumber(value: UInt.max).intValue, 4294967295)
+#endif
             XCTAssertEqual(NSNumber(value: UInt.max).uintValue, 4294967295)
 
             XCTAssertEqual(NSNumber(value: UInt.max).floatValue, Float(UInt.max))
@@ -763,7 +809,9 @@
             XCTAssertEqual(NSNumber(value: UInt.max).uint64Value, 18446744073709551615)
 
             XCTAssertEqual(NSNumber(value: UInt.max).intValue, -1)
+#if !arch(arm)
             XCTAssertEqual(NSNumber(value: UInt.max).uintValue, 18446744073709551615)
+#endif
 
             XCTAssertEqual(NSNumber(value: UInt.max).floatValue, Float(UInt.max))
             XCTAssertEqual(NSNumber(value: UInt.max).doubleValue, Double(UInt.max))
diff --git a/TestFoundation/TestNSString.swift b/TestFoundation/TestNSString.swift
index e75bd4f..45edeb6 100644
--- a/TestFoundation/TestNSString.swift
+++ b/TestFoundation/TestNSString.swift
@@ -49,16 +49,13 @@
             ("test_isNotEqualToObjectWithNSNumber", test_isNotEqualToObjectWithNSNumber ),
             ("test_FromASCIIData", test_FromASCIIData ),
             ("test_FromUTF8Data", test_FromUTF8Data ),
-            // Swift3 updates broke the expectations of this test. disabling for now
-            // ("test_FromMalformedUTF8Data", test_FromMalformedUTF8Data ),
+            ("test_FromMalformedUTF8Data", test_FromMalformedUTF8Data ),
             ("test_FromASCIINSData", test_FromASCIINSData ),
             ("test_FromUTF8NSData", test_FromUTF8NSData ),
-            // Swift3 updates broke the expectations of this test. disabling for now
-            // ("test_FromMalformedUTF8NSData", test_FromMalformedUTF8NSData ),
+            ("test_FromMalformedUTF8NSData", test_FromMalformedUTF8NSData ),
             ("test_FromNullTerminatedCStringInASCII", test_FromNullTerminatedCStringInASCII ),
             ("test_FromNullTerminatedCStringInUTF8", test_FromNullTerminatedCStringInUTF8 ),
-            // Swift3 updates broke the expectations of this test. disabling for now
-            // ("test_FromMalformedNullTerminatedCStringInUTF8", test_FromMalformedNullTerminatedCStringInUTF8 ),
+            ("test_FromMalformedNullTerminatedCStringInUTF8", test_FromMalformedNullTerminatedCStringInUTF8 ),
             ("test_uppercaseString", test_uppercaseString ),
             ("test_lowercaseString", test_lowercaseString ),
             ("test_capitalizedString", test_capitalizedString ),
@@ -913,7 +910,7 @@
             let path = NSString(string: "~\(userName)/")
             let result = path.expandingTildeInPath
           	// next assert fails in VirtualBox because home directory for unknown user resolved to /var/run/vboxadd
-            XCTAssert(result == "~\(userName)", "Return copy of reciver if home directory could no be resolved.")
+            XCTAssertEqual(result, "~\(userName)", "Return copy of receiver if home directory could not be resolved.")
         }
     }
     
diff --git a/TestFoundation/TestNumberFormatter.swift b/TestFoundation/TestNumberFormatter.swift
index 02914ad..7a470b2 100644
--- a/TestFoundation/TestNumberFormatter.swift
+++ b/TestFoundation/TestNumberFormatter.swift
@@ -162,9 +162,11 @@
         numberFormatter.plusSign = sign
         XCTAssertEqual(numberFormatter.plusSign, sign)
 
+#if !os(Android)
         let formattedString = numberFormatter.string(from: 420000000000000000)
         XCTAssertNotNil(formattedString)
         XCTAssertEqual(formattedString, "4.2E👍17")
+#endif
 
         // Verify a negative exponent does not have the 👍
         let noPlusString = numberFormatter.string(from: -0.420)
diff --git a/TestFoundation/TestProcess.swift b/TestFoundation/TestProcess.swift
index d19340b..8ebc3ce 100644
--- a/TestFoundation/TestProcess.swift
+++ b/TestFoundation/TestProcess.swift
@@ -17,6 +17,9 @@
 
 class TestProcess : XCTestCase {
     static var allTests: [(String, (TestProcess) -> () throws -> Void)] {
+#if os(Android)
+	return []
+#else
         return [
                    ("test_exit0" , test_exit0),
                    ("test_exit1" , test_exit1),
@@ -34,8 +37,10 @@
                    ("test_no_environment", test_no_environment),
                    ("test_custom_environment", test_custom_environment),
         ]
+#endif
     }
     
+#if !os(Android)
     func test_exit0() {
         
         let process = Process()
@@ -281,6 +286,7 @@
             XCTFail("Test failed: \(error)")
         }
     }
+#endif
 }
 
 private func mkstemp(template: String, body: (FileHandle) throws -> Void) rethrows {
@@ -303,6 +309,7 @@
     case InvalidEnvironmentVariable(String)
 }
 
+#if !os(Android)
 private func runTask(_ arguments: [String], environment: [String: String]? = nil, currentDirectoryPath: String? = nil) throws -> (String, String) {
     let process = Process()
 
@@ -353,5 +360,5 @@
     }
     return result
 }
-
+#endif
 
diff --git a/TestFoundation/TestThread.swift b/TestFoundation/TestThread.swift
index 6098b02..f5b224b 100644
--- a/TestFoundation/TestThread.swift
+++ b/TestFoundation/TestThread.swift
@@ -20,6 +20,9 @@
 
 class TestThread : XCTestCase {
     static var allTests: [(String, (TestThread) -> () throws -> Void)] {
+#if os(Android)
+        return []
+#endif
         return [
             ("test_currentThread", test_currentThread ),
             ("test_threadStart", test_threadStart),
diff --git a/TestFoundation/TestTimeZone.swift b/TestFoundation/TestTimeZone.swift
index d696c93..2bbb523 100644
--- a/TestFoundation/TestTimeZone.swift
+++ b/TestFoundation/TestTimeZone.swift
@@ -121,6 +121,9 @@
     }
     
     func test_localizedName() {
+#if os(Android)
+	XCTFail("Named timezones not available on Android")
+#else
         let initialTimeZone = NSTimeZone.default
         NSTimeZone.default = TimeZone(identifier: "America/New_York")!
         let defaultTimeZone = NSTimeZone.default
@@ -132,6 +135,7 @@
         XCTAssertEqual(defaultTimeZone.localizedName(for: .shortDaylightSaving, locale: locale), "EDT")
         XCTAssertEqual(defaultTimeZone.localizedName(for: .shortGeneric, locale: locale), "ET")
         NSTimeZone.default = initialTimeZone //reset the TimeZone
+#endif
     }
 
     func test_initializingTimeZoneWithOffset() {
diff --git a/TestFoundation/TestURL.swift b/TestFoundation/TestURL.swift
index 1ce0bf9..0a9b652 100644
--- a/TestFoundation/TestURL.swift
+++ b/TestFoundation/TestURL.swift
@@ -78,6 +78,9 @@
         #if os(OSX)
         let baseURL = URL(fileURLWithPath: homeDirectory, isDirectory: true)
         let relativePath = "Documents"
+        #elseif os(Android)
+        let baseURL = URL(fileURLWithPath: "/data", isDirectory: true)
+        let relativePath = "local"
         #elseif os(Linux)
         let baseURL = URL(fileURLWithPath: "/usr", isDirectory: true)
         let relativePath = "include"
@@ -260,6 +263,10 @@
             return false
         }
         
+        #if os(Android)
+        chdir("/data/local/tmp")
+        #endif
+
         let cwd = FileManager.default.currentDirectoryPath
         let cwdURL = URL(fileURLWithPath: cwd, isDirectory: true)
         // 1 for path separator
@@ -309,7 +316,7 @@
         let actualLength = strlen(fileSystemRep)
         // 1 for path separator
         let expectedLength = UInt(strlen(TestURL.gFileDoesNotExistName)) + TestURL.gRelativeOffsetFromBaseCurrentWorkingDirectory
-        XCTAssertTrue(UInt(actualLength) == expectedLength, "fileSystemRepresentation was too short")
+        XCTAssertEqual(UInt(actualLength), expectedLength, "fileSystemRepresentation was too short")
         XCTAssertTrue(strncmp(TestURL.gBaseCurrentWorkingDirectoryPath, fileSystemRep, Int(strlen(TestURL.gBaseCurrentWorkingDirectoryPath))) == 0, "fileSystemRepresentation of base path is wrong")
         let lengthOfRelativePath = Int(strlen(TestURL.gFileDoesNotExistName))
         let relativePath = fileSystemRep.advanced(by: Int(TestURL.gRelativeOffsetFromBaseCurrentWorkingDirectory))
@@ -364,7 +371,7 @@
         let actualLength = UInt(strlen(fileSystemRep))
         // 1 for path separator
         let expectedLength = UInt(strlen(TestURL.gFileDoesNotExistName)) + TestURL.gRelativeOffsetFromBaseCurrentWorkingDirectory
-        XCTAssertTrue(actualLength == expectedLength, "fileSystemRepresentation was too short")
+        XCTAssertEqual(actualLength, expectedLength, "fileSystemRepresentation was too short")
         XCTAssertTrue(strncmp(TestURL.gBaseCurrentWorkingDirectoryPath, fileSystemRep, Int(strlen(TestURL.gBaseCurrentWorkingDirectoryPath))) == 0, "fileSystemRepresentation of base path is wrong")
         let lengthOfRelativePath = Int(strlen(TestURL.gFileDoesNotExistName))
         let relativePath = fileSystemRep.advanced(by: Int(TestURL.gRelativeOffsetFromBaseCurrentWorkingDirectory))
@@ -426,7 +433,11 @@
     }
     
     func test_reachable() {
+        #if os(Android)
+        var url = URL(fileURLWithPath: "/data")
+        #else
         var url = URL(fileURLWithPath: "/usr")
+        #endif
         XCTAssertEqual(true, try? url.checkResourceIsReachable())
         
         url = URL(string: "https://www.swift.org")!
@@ -451,7 +462,11 @@
             XCTFail()
         }
         
+        #if os(Android)
+        var nsURL = NSURL(fileURLWithPath: "/data")
+        #else
         var nsURL = NSURL(fileURLWithPath: "/usr")
+        #endif
         XCTAssertEqual(true, try? nsURL.checkResourceIsReachable())
         
         nsURL = NSURL(string: "https://www.swift.org")!
diff --git a/TestFoundation/TestURLSession.swift b/TestFoundation/TestURLSession.swift
index c941f1c..0a535e9 100644
--- a/TestFoundation/TestURLSession.swift
+++ b/TestFoundation/TestURLSession.swift
@@ -212,6 +212,9 @@
     }
     
     func test_cancelTask() {
+#if os(Android)
+        XCTFail("Intermittent failures on Android")
+#else
         let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/Peru"
         let url = URL(string: urlString)!
         let d = DataTask(with: expectation(description: "GET \(urlString): task cancelation"))
@@ -219,6 +222,7 @@
         d.run(with: url)
         d.cancel()
         waitForExpectations(timeout: 12)
+#endif
     }
     
     func test_verifyRequestHeaders() {
@@ -467,10 +471,16 @@
     }
 
     func test_concurrentRequests() {
+#if os(Android)
+        let tasks = 10
+        XCTFail("640 tasks causes other tests to fail on Android")
+#else
+        let tasks = 640
+#endif
         let syncQ = dispatchQueueMake("test_dataTaskWithURL.syncQ")
         var dataTasks: [DataTask] = []
         let g = dispatchGroupMake()
-        for f in 0..<640 {
+        for f in 0..<tasks {
             g.enter()
             let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/Nepal"
             let expectation = self.expectation(description: "GET \(urlString) [\(f)]: with a delegate")
diff --git a/TestFoundation/main.swift b/TestFoundation/main.swift
index a1f6bf9..227c609 100644
--- a/TestFoundation/main.swift
+++ b/TestFoundation/main.swift
@@ -111,4 +111,5 @@
     testCase(TestJSONEncoder.allTests),
     testCase(TestCodable.allTests),
     testCase(TestUnit.allTests),
+    testCase(TestNSLock.allTests),
 ])
diff --git a/android/README.md b/android/README.md
deleted file mode 100644
index ef274b1..0000000
--- a/android/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-
-## Android Port of Foundation module
-
-This directory contains scripts used in the port of Foundation to
-an Android toolchain. The short version of the story is that after
-downloading the swift sources use the script "prepare.sh" in this
-directory to install prebuilt binaries and headers for libxml,
-libcurl and libdispatch then run the script "builder.sh".
-
-This build requires the path to a [r12 Android NDK](http://developer.android.com/ndk/downloads/index.html) in the
-`ANDROID_NDK_HOME` environment variable and the path to the
-android port of the "icu" libraries in `ANDROID_ICU_UC`
-downloaded from [here](https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz).
-The port was tested against api 21 on a Android v5.1.1 LG K4 Phone (Lollipop)
-and requires an Ubuntu 15 host with the Android NDK Gold linker from
-`toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin` installed as /usr/bin/ld.gold.
-
-The pre-built binaries were built from the following repos:
-
-[https://github.com/curl/curl](https://github.com/curl/curl)
-
-[https://github.com/android/platform_external_libxml2](https://github.com/android/platform_external_libxml2)
-
-[https://github.com/apple/swift-corelibs-libdispatch](https://github.com/apple/swift-corelibs-libdispatch)
-
-[https://github.com/mheily/libpwq](https://github.com/mheily/libpwq)
-
-[https://github.com/mheily/libkqueue](https://github.com/mheily/libkqueue)
-
-To build these the recipe was generally the same. autogen or configure
-for Linux then alter their Makefiles to have CFLAGS = include: --target=armv7-none-linux-androideabi --sysroot=$(ANDROID_NDK_HOME)/platforms/android-21/arch-arm.
-
-There is a known issue when libdispatch background tasks exit
-they will cause an exception as DetachCurrentThread has not
-been called. To avoid this your app must include the line:
-
-   DispatchGroup.threadCleanupCallback = JNI_DetachCurrentThread
-
-JNI_DetachCurrentThread is available in the package java_swift
-available here: https://github.com/SwiftJava/java_swift
-
-Pre-built binaries of an Swift compiler with support for Android
-including Foundation available here:
-
-http://johnholdsworth.com/android_toolchain.tgz
-
-### Other resources
-
-Check out the [SwiftAndroid](https://github.com/SwiftAndroid) and
-[SwiftJava](https://github.com/SwiftJava) github projects for
-starter Android applications and resources.
diff --git a/android/builder.sh b/android/builder.sh
deleted file mode 100755
index d00b8da..0000000
--- a/android/builder.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash -x
-#
-# Build Android toolchain including Foundation
-#
-
-cd "$(dirname $0)" &&
-#./prepare.sh &&
-./install.sh -u &&
-
-pushd "../../swift" &&
-./utils/build-script \
-    -R --skip-build-libdispatch --foundation \
-    --android \
-    --android-ndk "${ANDROID_NDK_HOME:?Please set ANDROID_NDK_HOME to path to an Android NDK downloaded from http://developer.android.com/ndk/downloads/index.html}" \
-    --android-api-level 21 \
-    --android-icu-uc "${ANDROID_ICU_UC:?Please set ANDROID_ICU_UC to path to Android ICU downloaded from https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz}/armeabi-v7a" \
-    --android-icu-uc-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/common" \
-    --android-icu-i18n "${ANDROID_ICU_UC}/armeabi-v7a" \
-    --android-icu-i18n-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/i18n" &&
-
-popd && ./install.sh
diff --git a/android/install.sh b/android/install.sh
deleted file mode 100755
index c724695..0000000
--- a/android/install.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-#
-# Simple script to move Android Foundation into toolchain
-# To build it again after this, use install.sh -u to reset
-#
-
-cd "$(dirname $0)"
-
-SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))"
-BUILD_DIR="$(dirname $SWIFT_ROOT)"
-
-if [[ "$1" == "-u" ]]; then
-    rm -rf "${SWIFT_ROOT}/lib/swift/CoreFoundation"
-    exit
-fi
-
-\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/libFoundation.so" "${SWIFT_ROOT}/lib/swift/android" &&
-
-\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/Foundation.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" &&
-
-rsync -arv "${BUILD_DIR}/foundation-linux-x86_64/Foundation/usr/lib/swift/CoreFoundation" "${SWIFT_ROOT}/lib/swift/"
diff --git a/android/package.sh b/android/package.sh
deleted file mode 100755
index 4657c49..0000000
--- a/android/package.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-#
-# Prepare binary package used to build Foundation for Android
-#
-
-cd "$(dirname $0)" &&
-TAR_FILE="$(pwd)/android_dispatch" &&
-
-cd "../../platform_external_libxml2/include" &&
-tar cf "$TAR_FILE.tar" libxml &&
-
-cd "../../curl/include" &&
-tar rf "$TAR_FILE.tar" curl &&
-
-cd "$(dirname $(dirname $(which swiftc)))/lib/swift" &&
-
-tar rf "$TAR_FILE.tar" dispatch android/lib{xml2,curl,dispatch}.so android/armv7/Dispatch.swift* &&
-
-gzip "$TAR_FILE.tar" &&
-\mv "$TAR_FILE.tar.gz" "$TAR_FILE.tgz" &&
-
-tar tfvz "$TAR_FILE.tgz"
diff --git a/android/prepare.sh b/android/prepare.sh
deleted file mode 100755
index 5e3ce2d..0000000
--- a/android/prepare.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Prepare swift sourcerelease to build Foundation for Android
-#
-
-BUILD_DIR="build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift"
-
-cd "$(dirname $0)" &&
-TAR_FILE="$(pwd)/android_dispatch.tgz" &&
-
-if [[ ! -f "${TAR_FILE}" ]]; then
-    echo "Fetching binaries and headers for libxml2, libcurl and libdispatch"
-    curl "https://raw.githubusercontent.com/SwiftJava/SwiftJava/master/android_dispatch.tgz" > "${TAR_FILE}"
-fi
-
-cd "../.." && mkdir -p "${BUILD_DIR}" &&
-cd "${BUILD_DIR}" && tar xfvz "${TAR_FILE}"
diff --git a/android/updater.sh b/android/updater.sh
deleted file mode 100755
index 1dcd2c7..0000000
--- a/android/updater.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-#
-# Move freshly built dependencies for Foundation into
-# build directory to be available for it's compilation.
-#
-# libxml2.so built from the android platform port:
-# https://github.com/android/platform_external_libxml2
-#
-# This is the most useful page found but it's not complete
-# http://stackoverflow.com/questions/12052089/using-libxml-for-android
-# Don't set CFLAGS or LDFLAGS and use ./autogen.sh instead of "configure"
-# Remove HTMLparser.lo and HTMLtree.lo from the Makefile and make sure
-# LIBXML_HTML_ENABLED and LIBXML_ICONV_ENABLED were not enabled in file
-# "include/libxml/xmlversion.h". Add the following to CFLAGS in Makefile:
-# -nostdlib --target=armv7-none-linux-androideabi
-# --sysroot=$ANDROID_NDK/platforms/android-21/arch-arm
-#
-# libcurl.so is built similarly from https://github.com/curl/curl
-#
-# libdispatch.so is a difficult build soon to be automated by another PR.
-#
-
-ANDROID_ICU_UC="${ANDROID_ICU_UC:-$HOME/libiconv-libicu-android}"
-
-cd "$(dirname $0)" &&
-
-SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))" &&
-BUILD_DIR="$(dirname $SWIFT_ROOT)" &&
-
-\cp -v ../../platform_external_libxml2/libxml2.so ../../curl/libcurl.so ../../swift-corelibs-libdispatch/libdispatch.so "$ANDROID_ICU_UC"/armeabi-v7a/libicu*.so "${SWIFT_ROOT}/lib/swift/android" &&
-
-\cp -v "${BUILD_DIR}/libdispatch-linux-x86_64/src/swift/Dispatch.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" &&
-
-rsync -arv "../../swift-corelibs-libdispatch/dispatch" "${SWIFT_ROOT}/lib/swift/" &&
-
-\cp -v "../../swift-corelibs-libdispatch/private/"*.h "${SWIFT_ROOT}/lib/swift/dispatch" &&
-
-rpl -R -e libicu libscu "${SWIFT_ROOT}/lib/swift/android"/lib{icu,swift,Foundation,xml2}*.so &&
-
-for i in "${SWIFT_ROOT}/lib/swift/android"/libicu*.so; do \mv -f $i ${i/libicu/libscu}; done
diff --git a/build-android b/build-android
new file mode 100755
index 0000000..055f472
--- /dev/null
+++ b/build-android
@@ -0,0 +1,141 @@
+#!/usr/bin/env bash
+#
+# build-android
+#
+# 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 https://swift.org/LICENSE.txt for license information
+# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+set -e
+
+SWIFT_PATH="$( cd "$(dirname $0)/.." && pwd )" 
+
+ANDROID_NDK_PATH="${ANDROID_NDK_PATH:?Please set the Android NDK path in the ANDROID_NDK_PATH environment variable}"
+ANDROID_ICU_PATH=${SWIFT_PATH}/libiconv-libicu-android
+
+SWIFT_ANDROID_TOOLCHAIN_PATH="${SWIFT_PATH}/swift-android-toolchain"
+SWIFT_ANDROID_BUILD_PATH="${SWIFT_PATH}/build/Ninja-ReleaseAssert"
+
+cd ${SWIFT_PATH}/swift-corelibs-foundation
+
+mkdir -p .build
+cd .build
+
+ANDROID_STANDALONE_TOOLCHAIN=`realpath ./android-standalone-toolchain`
+ANDROID_STANDALONE_SYSROOT=$ANDROID_STANDALONE_TOOLCHAIN/sysroot
+
+if [ ! -d android-standalone-toolchain ]; then
+    echo Creating Android standalone toolchain ...
+    $ANDROID_NDK_PATH/build/tools/make_standalone_toolchain.py --api 21 --arch arm --stl libc++ --install-dir $ANDROID_STANDALONE_TOOLCHAIN --force -v
+fi
+
+export PATH=$ANDROID_STANDALONE_TOOLCHAIN/bin:$PATH
+export CC=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-clang
+export CXX=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-clang++
+export AR=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-ar
+export AS=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-as
+export LD=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-ld
+export RANLIB=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-ranlib
+export NM=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-nm
+export STRIP=$ANDROID_STANDALONE_TOOLCHAIN/bin/arm-linux-androideabi-strip
+export CHOST=arm-linux-androideabi
+export ARCH_FLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
+export ARCH_LINK="-march=armv7-a -Wl,--fix-cortex-a8"
+export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing "
+export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -frtti -fexceptions -std=c++11 -Wno-error=unused-command-line-argument "
+export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing "
+export LDFLAGS=" ${ARCH_LINK} "
+
+if [ ! -d curl ]; then
+    git clone https://github.com/curl/curl.git
+fi
+if [ ! -f $ANDROID_STANDALONE_SYSROOT/usr/lib/libcurl.so ]; then
+    pushd curl
+        autoreconf -i
+        ./configure --host=arm-linux-androideabi --enable-shared --disable-static --disable-dependency-tracking --with-zlib=$ANDROID_STANDALONE_SYSROOT/usr --with-ssl=$ANDROID_STANDALONE_SYSROOT/usr --without-ca-bundle --without-ca-path --enable-ipv6 --enable-http --enable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-sspi --disable-manual --target=arm-linux-androideabi --build=x86_64-unknown-linux-gnu --prefix=$ANDROID_STANDALONE_SYSROOT/usr
+        make
+        make install
+    popd
+fi
+if [ ! -d libxml2 ]; then
+    git clone git://git.gnome.org/libxml2
+fi
+if [ ! -f $ANDROID_STANDALONE_SYSROOT/usr/lib/libxml2.so ]; then
+    pushd libxml2
+        autoreconf -i
+        ./configure --with-sysroot=$ANDROID_STANDALONE_SYSROOT --with-zlib=$ANDROID_STANDALONE_SYSROOT/usr --prefix=$ANDROID_STANDALONE_SYSROOT/usr --host=$CHOST --without-lzma --disable-static --enable-shared --without-http --without-html --without-ftp
+        make libxml2.la 
+        make install-libLTLIBRARIES 
+        pushd include
+            make install
+        popd
+    popd
+fi
+if [ ! -f libFoundation.so ]; then
+    pushd $ANDROID_STANDALONE_SYSROOT
+
+        # Move dispatch public and private headers to the directory foundation is expecting to get it
+        mkdir -p $ANDROID_STANDALONE_SYSROOT/usr/include/dispatch
+        cp $SWIFT_PATH/swift-corelibs-libdispatch/dispatch/*.h $ANDROID_STANDALONE_SYSROOT/usr/include/dispatch
+        cp $SWIFT_PATH/swift-corelibs-libdispatch/private/*.h $ANDROID_STANDALONE_SYSROOT/usr/include/dispatch
+	
+        pushd $SWIFT_PATH
+            pushd swift-corelibs-foundation
+                # Libfoundation script is not completely prepared to handle cross compilation yet.
+                ln -sf $SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64/lib/swift $ANDROID_STANDALONE_SYSROOT/usr/lib/
+                cp $SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64/lib/swift/android/armv7/* $SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64/lib/swift/android/
+
+                # Search path for curl seems to be wrong in foundation
+                #cp -r .build/openssl-1.0.2l/ssl $ANDROID_STANDALONE_SYSROOT/usr/include
+                cp -r .build/curl/include/curl $ANDROID_STANDALONE_SYSROOT/usr/include
+                if [ ! -e $ANDROID_STANDALONE_SYSROOT/usr/include/curl/curl ]; then
+                    ln -s $ANDROID_STANDALONE_SYSROOT/usr/include/curl $ANDROID_STANDALONE_SYSROOT/usr/include/curl/curl
+                fi
+                if [ ! -e $ANDROID_STANDALONE_SYSROOT/usr/include/libxml ]; then
+                    ln -s $ANDROID_STANDALONE_SYSROOT/usr/include/libxml2/libxml $ANDROID_STANDALONE_SYSROOT/usr/include/libxml
+                fi
+ 
+                env \
+                    SWIFTC="$SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64/bin/swiftc" \
+                    CLANG="$SWIFT_ANDROID_BUILD_PATH/llvm-linux-x86_64/bin/clang" \
+                    SWIFT="$SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64/bin/swift" \
+                    SDKROOT="$SWIFT_ANDROID_BUILD_PATH/swift-linux-x86_64" \
+                    BUILD_DIR="$SWIFT_ANDROID_BUILD_PATH/foundation-linux-x86_64" \
+                    DSTROOT="/" \
+                    PREFIX="/usr" \
+                    CFLAGS="-DDEPLOYMENT_TARGET_ANDROID -DDEPLOYMENT_ENABLE_LIBDISPATCH --sysroot=$ANDROID_NDK_PATH/platforms/android-21/arch-arm -I$ANDROID_ICU_PATH/armeabi-v7a/include -I${SDKROOT}/lib/swift -I$ANDROID_NDK_PATH/sources/android/support/include -I$ANDROID_STANDALONE_SYSROOT/usr/include -I$SWIFT_PATH/swift-corelibs-foundation/closure" \
+                    SWIFTCFLAGS="-DDEPLOYMENT_TARGET_ANDROID -DDEPLOYMENT_ENABLE_LIBDISPATCH -I$ANDROID_NDK_PATH/platforms/android-21/arch-arm/usr/include" \
+                    LDFLAGS="-fuse-ld=gold --sysroot=$ANDROID_NDK_PATH/platforms/android-21/arch-arm -L$ANDROID_NDK_PATH/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x -L$ANDROID_ICU_PATH/armeabi-v7a -L$ANDROID_STANDALONE_SYSROOT/usr/lib -ldispatch " \
+                    ./configure \
+                        Release \
+                        --target=armv7-none-linux-androideabi \
+                        --sysroot=$ANDROID_STANDALONE_SYSROOT \
+                        -DXCTEST_BUILD_DIR=$SWIFT_ANDROID_BUILD_PATH/xctest-linux-x86_64 \
+                        -DLIBDISPATCH_SOURCE_DIR=$SWIFT_PATH/swift-corelibs-libdispatch \
+                        -DLIBDISPATCH_BUILD_DIR=$SWIFT_PATH/swift-corelibs-libdispatch &&
+
+                cp -r /usr/include/uuid $ANDROID_STANDALONE_SYSROOT/usr/include 
+                sed -i~ "s/-I.\/ -I\/usr\/include\/x86_64-linux-gnu  -I\/usr\/include\/x86_64-linux-gnu    -I\/usr\/include\/libxml2//" build.ninja
+                sed -i~ "s/-licui18n/-licui18nswift/g" build.ninja
+                sed -i~ "s/-licuuc/-licuucswift/g" build.ninja
+                sed -i~ "s/-licudata/-licudataswift/g" build.ninja
+
+                ninja 
+		
+                # There's no installation script for foundation yet, so the installation needs to be done manually.
+                # Apparently the installation for the main script is in swift repo.
+                rsync -av $SWIFT_ANDROID_BUILD_PATH/foundation-linux-x86_64/Foundation/Foundation.swift* $SWIFT_ANDROID_TOOLCHAIN_PATH/usr/lib/swift/android/armv7/
+                rsync -av $ANDROID_STANDALONE_SYSROOT/usr/lib/libxml2.* $ANDROID_STANDALONE_SYSROOT/usr/lib/libcurl.* $ANDROID_ICU_PATH/armeabi-v7a/libicu{uc,i18n,data}swift.so $ANDROID_NDK_PATH/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so $SWIFT_ANDROID_BUILD_PATH/foundation-linux-x86_64/Foundation/libFoundation.so  $SWIFT_ANDROID_TOOLCHAIN_PATH/usr/lib/swift/android/armv7
+
+                # prep install so it can be used to build foundation
+                cp -r $SWIFT_PATH/swift-corelibs-foundation/.build/libxml2/include/libxml $SWIFT_ANDROID_TOOLCHAIN_PATH/usr/lib/swift
+                cp -r $SWIFT_PATH/swift-corelibs-foundation/.build/curl/include/curl $SWIFT_ANDROID_TOOLCHAIN_PATH/usr/lib/swift
+            popd
+        popd
+    popd
+fi
+