Implementation of most of the API for Progress. (#679)

This implementation is based on the Darwin NSProgress implementation. One important detail is that swift-corelibs-foundation we do not have Key-Value Observing (KVO) yet. In the meantime, it is suggested to use polling or some other mechanism to read the values.

Updates along the parent/child relationship in Progress are working.

One additional thing that remains is an implementation of the
localizedDescription methods. These are customized based on the contents
of the userInfo dictionary.
diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index 3e30c84..a16ff38 100755
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -331,6 +331,10 @@
 		E1A03F361C4828650023AF4D /* PropertyList-1.0.dtd in Resources */ = {isa = PBXBuildFile; fileRef = E1A03F351C4828650023AF4D /* PropertyList-1.0.dtd */; };
 		E1A03F381C482C730023AF4D /* NSXMLDTDTestData.xml in Resources */ = {isa = PBXBuildFile; fileRef = E1A03F371C482C730023AF4D /* NSXMLDTDTestData.xml */; };
 		E1A3726F1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml in Resources */ = {isa = PBXBuildFile; fileRef = E1A3726E1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml */; };
+		EA01AAEC1DA839C4008F4E07 /* TestProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA01AAEB1DA839C4008F4E07 /* TestProgress.swift */; };
+		EA0812691DA71C8A00651B70 /* ProgressFraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0812681DA71C8A00651B70 /* ProgressFraction.swift */; };
+		EA08126B1DA80C3600651B70 /* TestNSProgressFraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA08126A1DA80C3600651B70 /* TestNSProgressFraction.swift */; };
+		EA08126C1DA810BE00651B70 /* ProgressFraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0812681DA71C8A00651B70 /* ProgressFraction.swift */; };
 		EA418C261D57257D005EAD0D /* NSKeyedArchiverHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA418C251D57257D005EAD0D /* NSKeyedArchiverHelpers.swift */; };
 		EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */ = {isa = PBXBuildFile; fileRef = EA66F6351BEED03E00136161 /* TargetConditionals.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		EA66F6481BF1619600136161 /* NSURLTestData.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA66F63B1BF1619600136161 /* NSURLTestData.plist */; };
@@ -371,7 +375,7 @@
 		EADE0BAF1BD15E0000C49C64 /* NSPersonNameComponentsFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B711BD15DFF00C49C64 /* NSPersonNameComponentsFormatter.swift */; };
 		EADE0BB01BD15E0000C49C64 /* NSPort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B721BD15DFF00C49C64 /* NSPort.swift */; };
 		EADE0BB11BD15E0000C49C64 /* NSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B731BD15DFF00C49C64 /* NSPredicate.swift */; };
-		EADE0BB21BD15E0000C49C64 /* NSProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B741BD15DFF00C49C64 /* NSProgress.swift */; };
+		EADE0BB21BD15E0000C49C64 /* Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B741BD15DFF00C49C64 /* Progress.swift */; };
 		EADE0BB31BD15E0000C49C64 /* NSRegularExpression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B751BD15DFF00C49C64 /* NSRegularExpression.swift */; };
 		EADE0BB51BD15E0000C49C64 /* NSScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B771BD15DFF00C49C64 /* NSScanner.swift */; };
 		EADE0BB61BD15E0000C49C64 /* NSSortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B781BD15DFF00C49C64 /* NSSortDescriptor.swift */; };
@@ -768,6 +772,9 @@
 		E1A03F371C482C730023AF4D /* NSXMLDTDTestData.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = NSXMLDTDTestData.xml; sourceTree = "<group>"; };
 		E1A3726E1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = NSXMLDocumentTestData.xml; sourceTree = "<group>"; };
 		E876A73D1C1180E000F279EC /* TestNSRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSRange.swift; sourceTree = "<group>"; };
+		EA01AAEB1DA839C4008F4E07 /* TestProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestProgress.swift; sourceTree = "<group>"; };
+		EA0812681DA71C8A00651B70 /* ProgressFraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressFraction.swift; sourceTree = "<group>"; };
+		EA08126A1DA80C3600651B70 /* TestNSProgressFraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSProgressFraction.swift; sourceTree = "<group>"; };
 		EA313DFC1BE7F2E90060A403 /* CFURLComponents_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFURLComponents_Internal.h; sourceTree = "<group>"; };
 		EA313DFD1BE7F2E90060A403 /* CFURLComponents_URIParser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLComponents_URIParser.c; sourceTree = "<group>"; };
 		EA313DFE1BE7F2E90060A403 /* CFURLComponents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFURLComponents.c; sourceTree = "<group>"; };
@@ -829,7 +836,7 @@
 		EADE0B711BD15DFF00C49C64 /* NSPersonNameComponentsFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSPersonNameComponentsFormatter.swift; sourceTree = "<group>"; };
 		EADE0B721BD15DFF00C49C64 /* NSPort.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSPort.swift; sourceTree = "<group>"; };
 		EADE0B731BD15DFF00C49C64 /* NSPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSPredicate.swift; sourceTree = "<group>"; };
-		EADE0B741BD15DFF00C49C64 /* NSProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSProgress.swift; sourceTree = "<group>"; };
+		EADE0B741BD15DFF00C49C64 /* Progress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Progress.swift; sourceTree = "<group>"; };
 		EADE0B751BD15DFF00C49C64 /* NSRegularExpression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSRegularExpression.swift; sourceTree = "<group>"; };
 		EADE0B761BD15DFF00C49C64 /* NSRunLoop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSRunLoop.swift; sourceTree = "<group>"; };
 		EADE0B771BD15DFF00C49C64 /* NSScanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSScanner.swift; sourceTree = "<group>"; };
@@ -1339,6 +1346,8 @@
 				7900433A1CACD33E00ECCBF1 /* TestNSPredicate.swift */,
 				400E22641C1A4E58007C5933 /* TestNSProcessInfo.swift */,
 				EA66F6401BF1619600136161 /* TestNSPropertyList.swift */,
+				EA08126A1DA80C3600651B70 /* TestNSProgressFraction.swift */,
+				EA01AAEB1DA839C4008F4E07 /* TestProgress.swift */,
 				E876A73D1C1180E000F279EC /* TestNSRange.swift */,
 				5B0C6C211C1E07E600705A0E /* TestNSRegularExpression.swift */,
 				61E0117B1C1B554D000037DD /* TestNSRunLoop.swift */,
@@ -1660,7 +1669,8 @@
 				EADE0B6B1BD15DFF00C49C64 /* NSNull.swift */,
 				5BDC3F331BCC5DCB00ED97BB /* NSData.swift */,
 				5BA9BEA51CF3D747009DBD6C /* Data.swift */,
-				EADE0B741BD15DFF00C49C64 /* NSProgress.swift */,
+				EADE0B741BD15DFF00C49C64 /* Progress.swift */,
+				EA0812681DA71C8A00651B70 /* ProgressFraction.swift */,
 				5BDC3F381BCC5DCB00ED97BB /* NSError.swift */,
 				5BDC3F4B1BCC5DCB00ED97BB /* NSUUID.swift */,
 				6EB768271D18C12C00D4B719 /* UUID.swift */,
@@ -1973,6 +1983,7 @@
 				EADE0B9A1BD15DFF00C49C64 /* NSExpression.swift in Sources */,
 				EADE0BB01BD15E0000C49C64 /* NSPort.swift in Sources */,
 				EADE0BB91BD15E0000C49C64 /* NSTextCheckingResult.swift in Sources */,
+				EA0812691DA71C8A00651B70 /* ProgressFraction.swift in Sources */,
 				5BF7AEBE1BCD51F9008F214A /* NSTimeZone.swift in Sources */,
 				EADE0B951BD15DFF00C49C64 /* NSDateComponentsFormatter.swift in Sources */,
 				EADE0BBD1BD15E0000C49C64 /* NSURLCredential.swift in Sources */,
@@ -2029,7 +2040,7 @@
 				EADE0BA41BD15E0000C49C64 /* NSLengthFormatter.swift in Sources */,
 				5BDC3FCA1BCF176100ED97BB /* NSCFArray.swift in Sources */,
 				5B1FD9D61D6D16580080E83C /* HTTPBodySource.swift in Sources */,
-				EADE0BB21BD15E0000C49C64 /* NSProgress.swift in Sources */,
+				EADE0BB21BD15E0000C49C64 /* Progress.swift in Sources */,
 				EADE0B961BD15DFF00C49C64 /* NSDateIntervalFormatter.swift in Sources */,
 				6EB768281D18C12C00D4B719 /* UUID.swift in Sources */,
 				5B1FD9D41D6D16580080E83C /* Configuration.swift in Sources */,
@@ -2197,9 +2208,11 @@
 				5B13B34D1C582D4C00651CE2 /* TestNSUUID.swift in Sources */,
 				5B13B3281C582D4C00651CE2 /* TestNSBundle.swift in Sources */,
 				5B13B32A1C582D4C00651CE2 /* TestNSCharacterSet.swift in Sources */,
+				EA01AAEC1DA839C4008F4E07 /* TestProgress.swift in Sources */,
 				5B13B3411C582D4C00651CE2 /* TestNSRegularExpression.swift in Sources */,
 				5B13B3491C582D4C00651CE2 /* TestNSTimeZone.swift in Sources */,
 				5B13B34B1C582D4C00651CE2 /* TestNSURLRequest.swift in Sources */,
+				EA08126B1DA80C3600651B70 /* TestNSProgressFraction.swift in Sources */,
 				5B13B33E1C582D4C00651CE2 /* TestNSProcessInfo.swift in Sources */,
 				5B13B33F1C582D4C00651CE2 /* TestNSPropertyList.swift in Sources */,
 				5B13B32C1C582D4C00651CE2 /* TestNSDate.swift in Sources */,
@@ -2221,6 +2234,7 @@
 				5B13B34F1C582D4C00651CE2 /* TestNSXMLParser.swift in Sources */,
 				D5C40F331CDA1D460005690C /* TestNSOperationQueue.swift in Sources */,
 				5B13B32F1C582D4C00651CE2 /* TestNSGeometry.swift in Sources */,
+				EA08126C1DA810BE00651B70 /* ProgressFraction.swift in Sources */,
 				5B13B3351C582D4C00651CE2 /* TestNSKeyedUnarchiver.swift in Sources */,
 				5B13B33D1C582D4C00651CE2 /* TestNSPipe.swift in Sources */,
 				F9E0BB371CA70B8000F7FF3C /* TestNSURLCredential.swift in Sources */,
diff --git a/Foundation/NSProgress.swift b/Foundation/NSProgress.swift
deleted file mode 100644
index 1447783..0000000
--- a/Foundation/NSProgress.swift
+++ /dev/null
@@ -1,218 +0,0 @@
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See http://swift.org/LICENSE.txt for license information
-// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-
-/*
- Progress is used to report the amount of work done, and provides a way to allow the user to cancel that work.
- 
- Since work is often split up into several parts, progress objects can form a tree where children represent part of the overall total work. Each parent may have as many children as required, but each child only has one parent. The top level progress object in this tree is typically the one that you would display to a user. The leaf objects are updated as work completes, and the updates propagate up the tree.
- 
- The work that an Progress does is tracked via a "unit count." There are two unit count values: total and completed. In its leaf form, an Progress is created with a total unit count and its completed unit count is updated with -setCompletedUnitCount: until it matches the total unit count. The progress is then considered finished.
- 
- When progress objects form nodes in trees, they are still created with a total unit count. Portions of the total are then handed out to children as a "pending unit count." The total amount handed out to children should add up to the parent's totalUnitCount. When those children become finished, the pending unit count assigned to that child is added to the parent's completedUnitCount. Therefore, when all children are finished, the parent's completedUnitCount is equal to its totalUnitCount and it becomes finished itself.
- 
- Children Progress objects can be added implicitly or by invoking the -addChild:withPendingUnitCount: method on the parent. Implicitly added children are attached to a parent progress between a call to -becomeCurrentWithPendingUnitCount: and a call to -resignCurrent. The implicit child is created with the +progressWithTotalUnitCount: method or by passing the result of +currentProgress to the -initWithParent:userInfo: method. Both kinds of children can be attached to the same parent progress object. If you have an idea in advance that some portions of the work will take more or less time than the others, you can use different values of pending unit count for each child.
- 
- If you are designing an interface of an object that reports progress, then the recommended approach is to vend an Progress property and adopt the ProgressReporting protocol. The progress should be created with the -discreteProgressWithTotalUnitCount: method. You can then either update the progress object directly or set it to have children of its own. Users of your object can compose your progress into their tree by using the -addChild:withPendingUnitCount: method.
- 
- If you want to provide progress reporting for a single method, then the recommended approach is to implicitly attach to a current Progress by creating an Progress object at the very beginning of your method using +progressWithTotalUnitCount:. This progress object will consume the pending unit count, and then you can set up the progress object with children of its own.
-
- The localizedDescription and localizedAdditionalDescription properties are meant to be observed as well as set. So are the cancellable and pausable properties. totalUnitCount and completedUnitCount on the other hand are often not the best properties to observe when presenting progress to the user. For example, you should observe fractionCompleted instead of observing totalUnitCount and completedUnitCount and doing your own calculation. Progress' default implementation of fractionCompleted does fairly sophisticated things like taking child Progresses into account.
- */
-open class Progress : NSObject {
-    
-    /* The instance of Progress associated with the current thread by a previous invocation of -becomeCurrentWithPendingUnitCount:, if any. The purpose of this per-thread value is to allow code that does work to usefully report progress even when it is widely separated from the code that actually presents progress to the user, without requiring layers of intervening code to pass the instance of Progress through. Using the result of invoking this directly will often not be the right thing to do, because the invoking code will often not even know what units of work the current progress object deals in. Invoking +progressWithTotalUnitCount: to create a child Progress object and then using that to report progress makes more sense in that situation.
-    */
-    open class func current() -> Progress? { NSUnimplemented() }
-    
-    /* Return an instance of Progress that has been initialized with -initWithParent:userInfo:. The initializer is passed the current progress object, if there is one, and the value of the totalUnitCount property is set. In many cases you can simply precede code that does a substantial amount of work with an invocation of this method, with repeated invocations of -setCompletedUnitCount: and -isCancelled in the loop that does the work.
-    
-    You can invoke this method on one thread and then message the returned Progress on another thread. For example, you can let the result of invoking this method get captured by a block passed to dispatch_async(). In that block you can invoke methods like -becomeCurrentWithPendingUnitCount: and -resignCurrent, or -setCompletedUnitCount: and -isCancelled.
-    */
-    public init(totalUnitCount unitCount: Int64) { NSUnimplemented() }
-    
-    /* Return an instance of Progress that has been initialized with -initWithParent:userInfo:. The initializer is passed nil for the parent, resulting in a progress object that is not part of an existing progress tree. The value of the totalUnitCount property is also set.
-     */
-    open class func discreteProgress(totalUnitCount unitCount: Int64) -> Progress { NSUnimplemented() }
-    
-    /* Return an instance of Progress that has been attached to a parent progress with the given pending unit count.
-     */
-    public init(totalUnitCount unitCount: Int64, parent: Progress, pendingUnitCount portionOfParentTotalUnitCount: Int64) { NSUnimplemented() }
-    
-    /* The designated initializer. If a parent Progress object is passed then progress reporting and cancellation checking done by the receiver will notify or consult the parent. The only valid arguments to the first argument of this method are nil (indicating no parent) or [Progress currentProgress]. Any other value will throw an exception.
-    */
-    public init(parent parentProgressOrNil: Progress?, userInfo userInfoOrNil: [NSObject : AnyObject]?) { NSUnimplemented() }
-    
-    /* Make the receiver the current thread's current progress object, returned by +currentProgress. At the same time, record how large a portion of the work represented by the receiver will be represented by the next progress object initialized by invoking -initWithParent:userInfo: in the current thread with the receiver as the parent. This will be used when that child is sent -setCompletedUnitCount: and the receiver is notified of that.
-     
-       With this mechanism, code that doesn't know anything about its callers can report progress accurately by using +progressWithTotalUnitCount: and -setCompletedUnitCount:. The calling code will account for the fact that the work done is only a portion of the work to be done as part of a larger operation. The unit of work in a call to -becomeCurrentWithPendingUnitCount: has to be the same unit of work as that used for the value of the totalUnitCount property, but the unit of work used by the child can be a completely different one, and often will be. You must always balance invocations of this method with invocations of -resignCurrent.
-    */
-    open func becomeCurrent(withPendingUnitCount unitCount: Int64) { NSUnimplemented() }
-    
-    /* Balance the most recent previous invocation of -becomeCurrentWithPendingUnitCount: on the same thread by restoring the current progress object to what it was before -becomeCurrentWithPendingUnitCount: was invoked.
-    */
-    open func resignCurrent() { NSUnimplemented() }
-    
-    /* Directly add a child progress to the receiver, assigning it a portion of the receiver's total unit count.
-     */
-    open func addChild(_ child: Progress, withPendingUnitCount inUnitCount: Int64) { NSUnimplemented() }
-    
-    /* The size of the job whose progress is being reported, and how much of it has been completed so far, respectively. For an Progress with a kind of ProgressKindFile, the unit of these properties is bytes while the ProgressFileTotalCountKey and ProgressFileCompletedCountKey keys in the userInfo dictionary are used for the overall count of files. For any other kind of Progress, the unit of measurement you use does not matter as long as you are consistent. The values may be reported to the user in the localizedDescription and localizedAdditionalDescription.
-     
-       If the receiver Progress object is a "leaf progress" (no children), then the fractionCompleted is generally completedUnitCount / totalUnitCount. If the receiver Progress has children, the fractionCompleted will reflect progress made in child objects in addition to its own completedUnitCount. As children finish, the completedUnitCount of the parent will be updated.
-    */
-    open var totalUnitCount: Int64
-    public var completedUnitCount: Int64
-    
-    /* A description of what progress is being made, fit to present to the user. Progress is by default KVO-compliant for this property, with the notifications always being sent on thread which updates the property. The default implementation of the getter for this property does not always return the most recently set value of the property. If the most recently set value of this property is nil then Progress uses the value of the kind property to determine how to use the values of other properties, as well as values in the user info dictionary, to return a computed string. If it fails to do that then it returns an empty string.
-      
-      For example, depending on the kind of progress, the completed and total unit counts, and other parameters, these kinds of strings may be generated:
-        Copying 10 files…
-        30% completed
-        Copying “TextEdit”…
-    */
-    open var localizedDescription: String!
-    
-    /* A more specific description of what progress is being made, fit to present to the user. Progress is by default KVO-compliant for this property, with the notifications always being sent on thread which updates the property. The default implementation of the getter for this property does not always return the most recently set value of the property. If the most recently set value of this property is nil then Progress uses the value of the kind property to determine how to use the values of other properties, as well as values in the user info dictionary, to return a computed string. If it fails to do that then it returns an empty string. The difference between this and localizedDescription is that this text is meant to be more specific about what work is being done at any particular moment.
-    
-       For example, depending on the kind of progress, the completed and total unit counts, and other parameters, these kinds of strings may be generated:
-        3 of 10 files
-        123 KB of 789.1 MB
-        3.3 MB of 103.92 GB — 2 minutes remaining
-        1.61 GB of 3.22 GB (2 KB/sec) — 2 minutes remaining
-        1 minute remaining (1 KB/sec)
-    
-    */
-    open var localizedAdditionalDescription: String!
-    
-    /* Whether the work being done can be cancelled or paused, respectively. By default Progress is cancellable but not pausable. Progress is by default KVO-compliant for these properties, with the notifications always being sent on the thread which updates the property. These properties are for communicating whether controls for cancelling and pausing should appear in a progress reporting user interface. Progress itself does not do anything with these properties other than help pass their values from progress reporters to progress observers. It is valid for the values of these properties to change in virtually any way during the lifetime of an Progress. Of course, if an Progress is cancellable you should actually implement cancellability by setting a cancellation handler or by making your code poll the result of invoking -isCancelled. Likewise for pausability.
-    */
-    open var isCancellable: Bool
-    open var isPausable: Bool
-    
-    /* Whether the work being done has been cancelled or paused, respectively. Progress is by default KVO-compliant for these properties, with the notifications always being sent on the thread which updates the property. Instances of Progress that have parents are at least as cancelled or paused as their parents.
-    */
-    open var isCancelled: Bool { NSUnimplemented() }
-    open var isPaused: Bool { NSUnimplemented() }
-    
-    /* A block to be invoked when cancel is invoked. The block will be invoked even when the method is invoked on an ancestor of the receiver, or an instance of Progress in another process that resulted from publishing the receiver or an ancestor of the receiver. Your block won't be invoked on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
-    */
-    open var cancellationHandler: (() -> Void)?
-    
-    /* A block to be invoked when pause is invoked. The block will be invoked even when the method is invoked on an ancestor of the receiver, or an instance of Progress in another process that resulted from publishing the receiver or an ancestor of the receiver. Your block won't be invoked on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
-     */
-    open var pausingHandler: (() -> Void)?
-    
-    /* A block to be invoked when resume is invoked. The block will be invoked even when the method is invoked on an ancestor of the receiver, or an instance of Progress in another process that resulted from publishing the receiver or an ancestor of the receiver. Your block won't be invoked on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
-     */
-    open var resumingHandler: (() -> Void)?
-    
-    /* Set a value in the dictionary returned by invocations of -userInfo, with appropriate KVO notification for properties whose values can depend on values in the user info dictionary, like localizedDescription. If a nil value is passed then the dictionary entry is removed.
-    */
-    open func setUserInfoObject(_ objectOrNil: Any?, forKey key: String) { NSUnimplemented() }
-    
-    /* Whether the progress being made is indeterminate. -isIndeterminate returns YES when the value of the totalUnitCount or completedUnitCount property is less than zero. Zero values for both of those properties indicates that there turned out to not be any work to do after all; -isIndeterminate returns NO and -fractionCompleted returns 1.0 in that case. Progress is by default KVO-compliant for these properties, with the notifications always being sent on the thread which updates the property.
-    */
-    open var isIndeterminate: Bool { NSUnimplemented() }
-    
-    /* The fraction of the overall work completed by this progress object, including work done by any children it may have.
-    */
-    public var fractionCompleted: Double { NSUnimplemented() }
-    
-    /* Invoke the block registered with the cancellationHandler property, if there is one, and set the cancelled property to YES. Do this for the receiver, any descendants of the receiver, the instance of Progress that was published in another process to make the receiver if that's the case, and any descendants of such a published instance of Progress.
-    */
-    open func cancel() { NSUnimplemented() }
-    
-    /* Invoke the block registered with the pausingHandler property, if there is one, and set the paused property to YES. Do this for the receiver, any descendants of the receiver, the instance of Progress that was published in another process to make the receiver if that's the case, and any descendants of such a published instance of Progress.
-    */
-    open func pause() { NSUnimplemented() }
-    
-    /* Invoke the block registered with the resumingHandler property, if there is one, and set the paused property to NO. Do this for the receiver, any descendants of the receiver, the instance of Progress that was published in another process to make the receiver if that's the case, and any descendants of such a published instance of Progress.
-    */
-    open func resume() { NSUnimplemented() }
-    
-    /* Arbitrary values associated with the receiver. Returns a KVO-compliant dictionary that changes as -setUserInfoObject:forKey: is sent to the receiver. The dictionary will send all of its KVO notifications on the thread which updates the property. The result will never be nil, but may be an empty dictionary. Some entries have meanings that are recognized by the Progress class itself. See the Progress...Key string constants listed below.
-    */
-    open var userInfo: [ProgressUserInfoKey : Any] { NSUnimplemented() }
-    
-    /* Either a string identifying what kind of progress is being made, like ProgressKindFile, or nil. If the value of the localizedDescription property has not been set to a non-nil value then the default implementation of -localizedDescription uses the progress kind to determine how to use the values of other properties, as well as values in the user info dictionary, to create a string that is presentable to the user. This is most useful when -localizedDescription is actually being invoked in another process, whose localization language may be different, as a result of using the publish and subscribe mechanism described here.
-    */
-    open var kind: ProgressKind?
-    
-    public struct FileOperationKind : RawRepresentable, Equatable, Hashable, Comparable {
-        public let rawValue: String
-        public init(_ rawValue: String) { self.rawValue = rawValue }
-        public init(rawValue: String) { self.rawValue = rawValue }
-        public var hashValue: Int { return self.rawValue.hashValue }
-        public static func ==(_ lhs: FileOperationKind, _ rhs: FileOperationKind) -> Bool { return lhs.rawValue == rhs.rawValue }
-        public static func <(_ lhs: FileOperationKind, _ rhs: FileOperationKind) -> Bool { return lhs.rawValue < rhs.rawValue }
-        
-        public static let downloading = FileOperationKind(rawValue: "NSProgressFileOperationKindDownloading")
-        public static let decompressingAfterDownloading = FileOperationKind(rawValue: "NSProgressFileOperationKindDecompressingAfterDownloading")
-        public static let receiving = FileOperationKind(rawValue: "NSProgressFileOperationKindReceiving")
-        public static let copying = FileOperationKind(rawValue: "NSProgressFileOperationKindCopying")
-    }
-}
-
-/* If your class supports reporting progress, then you can adopt the ProgressReporting protocol. Objects that adopt this protocol should typically be "one-shot" -- that is, the progress is setup at initialization of the object and is updated when work is done. The value of the property should not be set to another progress object. Instead, the user of the ProgressReporting class should create a new instance to represent a new set of work.
- */
-public protocol ProgressReporting : NSObjectProtocol {
-    var progress: Progress { get }
-}
-
-public struct ProgressKind : RawRepresentable, Equatable, Hashable, Comparable {
-    public let rawValue: String
-    public init(_ rawValue: String) { self.rawValue = rawValue }
-    public init(rawValue: String) { self.rawValue = rawValue }
-    public var hashValue: Int { return self.rawValue.hashValue }
-    public static func ==(_ lhs: ProgressKind, _ rhs: ProgressKind) -> Bool { return lhs.rawValue == rhs.rawValue }
-    public static func <(_ lhs: ProgressKind, _ rhs: ProgressKind) -> Bool { return lhs.rawValue < rhs.rawValue }
-    
-    public static let file = ProgressKind(rawValue: "NSProgressKindFile")
-}
-
-public struct ProgressUserInfoKey : RawRepresentable, Equatable, Hashable, Comparable {
-    public let rawValue: String
-    public init(_ rawValue: String) { self.rawValue = rawValue }
-    public init(rawValue: String) { self.rawValue = rawValue }
-    public var hashValue: Int { return self.rawValue.hashValue }
-    public static func ==(_ lhs: ProgressUserInfoKey, _ rhs: ProgressUserInfoKey) -> Bool { return lhs.rawValue == rhs.rawValue }
-    public static func <(_ lhs: ProgressUserInfoKey, _ rhs: ProgressUserInfoKey) -> Bool { return lhs.rawValue < rhs.rawValue }
-    
-    /* How much time is probably left in the operation, as an NSNumber containing a number of seconds.
-     */
-    public static let estimatedTimeRemainingKey = ProgressUserInfoKey(rawValue: "NSProgressEstimatedTimeRemainingKey")
-    
-    
-    /* How fast data is being processed, as an NSNumber containing bytes per second.
-     */
-    public static let throughputKey = ProgressUserInfoKey(rawValue: "NSProgressThroughputKey")
-    
-    
-    /* The value for the kind property that indicates that the work being done is one of the kind of file operations listed below. NSProgress of this kind is assumed to use bytes as the unit of work being done and the default implementation of -localizedDescription takes advantage of that to return more specific text than it could otherwise. The NSProgressFileTotalCountKey and NSProgressFileCompletedCountKey keys in the userInfo dictionary are used for the overall count of files.
-     */
-    
-    /* A user info dictionary key, for an entry that is required when the value for the kind property is NSProgressKindFile. The value must be one of the strings listed in the next section. The default implementations of of -localizedDescription and -localizedItemDescription use this value to determine the text that they return.
-     */
-    public static let fileOperationKindKey = ProgressUserInfoKey(rawValue: "NSProgressFileOperationKindKey")
-    
-    
-    /* Possible values for NSProgressFileOperationKindKey entries.
-     */
-    
-    /* A user info dictionary key. The value must be an NSURL identifying the item on which progress is being made. This is required for any NSProgress that is published using -publish to be reported to subscribers registered with +addSubscriberForFileURL:withPublishingHandler:.
-     */
-    public static let fileURLKey = ProgressUserInfoKey(rawValue: "NSProgressFileURLKey")
-    
-    
-    /* User info dictionary keys. The values must be NSNumbers containing integers. These entries are optional but if they are both present then the default implementation of -localizedAdditionalDescription uses them to determine the text that it returns.
-     */
-    
-    public static let fileTotalCountKey = ProgressUserInfoKey(rawValue: "NSProgressFileTotalCountKey")
-    public static let fileCompletedCountKey = ProgressUserInfoKey(rawValue: "NSProgressFileCompletedCountKey")
-}
diff --git a/Foundation/Progress.swift b/Foundation/Progress.swift
new file mode 100644
index 0000000..3f16c2a
--- /dev/null
+++ b/Foundation/Progress.swift
@@ -0,0 +1,562 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+#if os(OSX) || os(iOS)
+import Darwin
+#elseif os(Linux)
+import Glibc
+#endif
+
+import Dispatch
+
+/**
+ `Progress` is used to report the amount of work done, and provides a way to allow the user to cancel that work.
+ 
+ Since work is often split up into several parts, progress objects can form a tree where children represent part of the overall total work. Each parent may have as many children as required, but each child only has one parent. The top level progress object in this tree is typically the one that you would display to a user. The leaf objects are updated as work completes, and the updates propagate up the tree.
+ 
+ The work that a `Progress` does is tracked via a "unit count." There are two unit count values: total and completed. In its leaf form, a `Progress` is created with a total unit count and its completed unit count is updated by setting `completedUnitCount` until it matches the `totalUnitCount`. The progress is then considered finished.
+ 
+ When progress objects form nodes in trees, they are still created with a total unit count. Portions of the total are then handed out to children as a "pending unit count." The total amount handed out to children should add up to the parent's `totalUnitCount`. When those children become finished, the pending unit count assigned to that child is added to the parent's `completedUnitCount`. Therefore, when all children are finished, the parent's `completedUnitCount` is equal to its `totalUnitCount` and it becomes finished itself.
+ 
+ Children `Progress` objects can be added implicitly or by calling `addChild(withPendingUnitCount)` on the parent. Implicitly added children are attached to a parent progress between a call to `becomeCurrent(withPendingUnitCount)` and a call to `resignCurrent`. The implicit child is created with the `Progress(totalUnitCount:)` initializer, or by passing the result of `Progress.currentProgress` to the `Progress(parent:userInfo:)` initializer. Both kinds of children can be attached to the same parent progress object. If you have an idea in advance that some portions of the work will take more or less time than the others, you can use different values of pending unit count for each child.
+ 
+ If you are designing an interface of an object that reports progress, then the recommended approach is to vend a `Progress` property and adopt the `ProgressReporting` protocol. The progress should be created with the `Progress.discreteProgress(withTotalUnitCount:)` class function. You can then either update the progress object directly or set it up to have children of its own. Users of your object can compose your progress into their tree by using the `addChild(withPendingUnitCount)` function.
+ 
+ If you want to provide progress reporting for a single method, then the recommended approach is to implicitly attach to a current `Progress` by creating an `Progress` object at the very beginning of your method using `Progress(withTotalUnitCount)`. This progress object will consume the pending unit count, and then you can set up the progress object with children of its own.
+
+ The `localizedDescription` and `localizedAdditionalDescription` properties are meant to be observed as well as set. So are the `cancellable` and `pausable` properties. `totalUnitCount` and `completedUnitCount`, on the other hand, are often not the best properties to observe when presenting progress to the user. You should observe `fractionCompleted` instead of observing `totalUnitCount` and `completedUnitCount` and doing your own calculation. `Progress`' default implementation of `fractionCompleted` does fairly sophisticated things like taking child `Progress` into account.
+ 
+ - note: In swift-corelibs-foundation, Key Value Observing is not yet available.
+ */
+open class Progress : NSObject {
+    
+    private weak var _parent : Progress?
+    private var _children : Set<Progress>
+    private var _selfFraction : _ProgressFraction
+    private var _childFraction : _ProgressFraction
+    private var _userInfo : [ProgressUserInfoKey : Any]
+    
+    // This is set once, but after initialization
+    private var _portionOfParent : Int64
+    
+    static private var _tsdKey = "_Foundation_CurrentProgressKey"
+    
+    /// The instance of `Progress` associated with the current thread by a previous invocation of `becomeCurrent(withPendingUnitCount:)`, if any. 
+    ///
+    /// The purpose of this per-thread value is to allow code that does work to usefully report progress even when it is widely separated from the code that actually presents progress to the user, without requiring layers of intervening code to pass the instance of `Progress` through. Using the result of invoking this directly will often not be the right thing to do, because the invoking code will often not even know what units of work the current progress object deals in. Using `Progress(withTotalUnitCount:)` to create a child `Progress` object and then using that to report progress makes more sense in that situation.
+    open class func current() -> Progress? {
+        return (Thread.current.threadDictionary[Progress._tsdKey] as? _ProgressTSD)?.currentProgress
+    }
+    
+    /// Initializes an instance of `Progress` with a parent of `Progress.current()`.
+    /// 
+    /// The value of the `totalUnitCount` property is also set. In many cases you can simply precede code that does a substantial amount of work with an invocation of this method, with repeated setting of the `completedUnitCount` property and synchronous checking of `isCancelled` in the loop that does the work.
+    public convenience init(totalUnitCount unitCount: Int64) {
+        self.init(parent: Progress.current())
+        totalUnitCount = unitCount
+    }
+    
+    /// Initializes an instance of `Progress` with a `nil` parent.
+    ///
+    /// The value of the `totalUnitCount` property is also set. The resulting progress object is not part of an existing progress tree.
+    open class func discreteProgress(totalUnitCount unitCount: Int64) -> Progress {
+        let progress = Progress(parent: nil)
+        progress.totalUnitCount = unitCount
+        return progress
+    }
+    
+    /// Initializes an instance of `Progress` with the specified total unit count, parent, and pending unit count.
+    public convenience init(totalUnitCount unitCount: Int64, parent: Progress, pendingUnitCount portionOfParentTotalUnitCount: Int64) {
+        self.init(parent: nil)
+        totalUnitCount = unitCount
+        parent.addChild(self, withPendingUnitCount: portionOfParentTotalUnitCount)
+    }
+    
+    /// Initializes an instance of `Progress` with the specified parent and user info dictionary.
+    public init(parent parentProgress: Progress?, userInfo userInfoOrNil: [ProgressUserInfoKey : Any]? = nil) {
+        _children = Set()
+        
+        isCancellable = false
+        isPausable = false
+        isCancelled = false
+        isPaused = false
+        
+        _selfFraction = _ProgressFraction()
+        _childFraction = _ProgressFraction()
+        
+        // It doesn't matter what the units are here as long as the total is non-zero
+        _childFraction.total = 1
+        
+        // This is reset later, if this progress becomes a child of some other progress
+        _portionOfParent = 0
+        
+        _userInfo = userInfoOrNil ?? [:]
+        
+        super.init()
+        
+        if let p = parentProgress {
+            precondition(p === Progress.current(), "The Parent must be the current progress")
+            p._addImplicitChild(self)
+        }
+    }
+    
+    /// MARK: -
+    
+    /// This is called when some other progress becomes an implicit child of this progress.
+    private func _addImplicitChild(_ child : Progress) {
+        guard let tsd = Thread.current.threadDictionary[Progress._tsdKey] as? _ProgressTSD else { preconditionFailure("A child was added without a current progress being set") }
+        
+        // We only allow one implicit child. More than that and things get confusing (and wrong) real quick.
+        if !tsd.childAttached {
+            addChild(child, withPendingUnitCount: tsd.pendingUnitCount)
+            tsd.childAttached = true
+        }
+    }
+    
+    /// Make this `Progress` the current thread's current progress object, returned by `Progress.currentProgress()`. 
+    ///
+    /// At the same time, record how large a portion of the work represented by the progress will be represented by the next progress object initialized with `Progress(parent:userInfo:)` in the current thread with this `Progress` as the parent. The portion of work will be used when the `completedUnitCount` of the child is set.
+    ///
+    /// With this mechanism, code that doesn't know anything about its callers can report progress accurately by using `Progress(withTotalUnitCount:)` and `completedUnitCount`. The calling code will account for the fact that the work done is only a portion of the work to be done as part of a larger operation.
+    ///
+    /// The unit of work in a call to `becomeCurrent(withPendingUnitCount:)` has to be the same unit of work as that used for the value of the `totalUnitCount` property, but the unit of work used by the child can be a completely different one, and often will be. 
+    ///
+    /// You must always balance invocations of this method with invocations of `resignCurrent`.
+    open func becomeCurrent(withPendingUnitCount unitCount: Int64) {
+        let oldTSD = Thread.current.threadDictionary[Progress._tsdKey] as? _ProgressTSD
+        if let checkedTSD = oldTSD {
+            precondition(checkedTSD.currentProgress !== self, "This Progress is already current on this thread.")
+        }
+        
+        let newTSD = _ProgressTSD(currentProgress: self, nextTSD: oldTSD, pendingUnitCount: unitCount)
+        Thread.current.threadDictionary[Progress._tsdKey] = newTSD
+    }
+    
+    /// Balance the most recent previous invocation of `becomeCurrent(withPendingUnitCount:)` on the same thread.
+    ///
+    /// This restores the current progress object to what it was before `becomeCurrent(withPendingUnitCount:)` was invoked.
+    open func resignCurrent() {
+        guard let oldTSD = Thread.current.threadDictionary[Progress._tsdKey] as? _ProgressTSD else {
+            preconditionFailure("This Progress was not the current progress on this thread.")
+        }
+        
+        if !oldTSD.childAttached {
+            // No children attached. Account for the completed unit count now.
+            _addCompletedUnitCount(oldTSD.pendingUnitCount)
+        }
+        
+        // Ok if the following is nil - then we clear the dictionary entry
+        let newTSD = oldTSD.nextTSD
+        Thread.current.threadDictionary[Progress._tsdKey] = newTSD
+    }
+    
+    /// Directly add a child progress to the receiver, assigning it a portion of the receiver's total unit count.
+    open func addChild(_ child: Progress, withPendingUnitCount inUnitCount: Int64) {
+        precondition(child._parent == nil, "The Progress was already the child of another Progress")
+        
+        _children.insert(child)
+        
+        child._setParent(self, portion: inUnitCount)
+        
+        if isCancelled {
+            child.cancel()
+        }
+        
+        if isPaused {
+            child.pause()
+        }
+    }
+    
+    private func _setParent(_ parent: Progress, portion: Int64) {
+        _parent = parent
+        _portionOfParent = portion
+        
+        // We need to tell the new parent what our fraction completed is
+        // The previous fraction is the same as if it didn't exist (0/0), but the new one represents our current state.
+        _parent?._updateChild(self, from: _ProgressFraction(completed: 0, total: 0), to: _overallFraction, portion: portion)
+    }
+    
+    /// How much of the job has been completed so far.
+    ///
+    /// For a `Progress` with a kind of `.file`, the unit of these properties is bytes while the `fileTotalCountKey` and `fileCompletedCountKey` keys in the `userInfo` dictionary are used for the overall count of files. For any other kind of `Progress`, the unit of measurement you use does not matter as long as you are consistent. The values may be reported to the user in the `localizedDescription` and `localizedAdditionalDescription`.
+    ///
+    /// If the `Progress` object is a "leaf progress" (no children), then the `fractionCompleted` is generally `completedUnitCount / totalUnitCount`. If the receiver `Progress` has children, the `fractionCompleted` will reflect progress made in child objects in addition to its own `completedUnitCount`. As children finish, the `completedUnitCount` of the parent will be updated.
+    open var totalUnitCount: Int64 {
+        get {
+            return _selfFraction.total
+        }
+        set {
+            let previous = _overallFraction
+            if _selfFraction.total != newValue && _selfFraction.total > 0 {
+                _childFraction = _childFraction * _ProgressFraction(completed: _selfFraction.total, total: newValue)
+            }
+            _selfFraction.total = newValue
+            _updateFractionCompleted(from: previous, to: _overallFraction)
+        }
+    }
+    
+    /// The size of the job whose progress is being reported.
+    ///
+    /// For a `Progress` with a kind of `.file`, the unit of these properties is bytes while the `fileTotalCountKey` and `fileCompletedCountKey` keys in the `userInfo` dictionary are used for the overall count of files. For any other kind of `Progress`, the unit of measurement you use does not matter as long as you are consistent. The values may be reported to the user in the `localizedDescription` and `localizedAdditionalDescription`.
+    ///
+    /// If the `Progress` object is a "leaf progress" (no children), then the `fractionCompleted` is generally `completedUnitCount / totalUnitCount`. If the receiver `Progress` has children, the `fractionCompleted` will reflect progress made in child objects in addition to its own `completedUnitCount`. As children finish, the `completedUnitCount` of the parent will be updated.
+    open var completedUnitCount: Int64 {
+        get {
+            return _selfFraction.completed
+        }
+        set {
+            let previous = _overallFraction
+            _selfFraction.completed = newValue
+            _updateFractionCompleted(from: previous, to: _overallFraction)
+        }
+    }
+    
+    /// A description of what progress is being made, fit to present to the user. 
+    ///
+    /// `Progress` is by default KVO-compliant for this property, with the notifications always being sent on thread which updates the property. The default implementation of the getter for this property does not always return the most recently set value of the property. If the most recently set value of this property is nil then `Progress` uses the value of the `kind` property to determine how to use the values of other properties, as well as values in the user info dictionary, to return a computed string. If it fails to do that then it returns an empty string.
+    ///
+    ///  For example, depending on the kind of progress, the completed and total unit counts, and other parameters, these kinds of strings may be generated:
+    ///    Copying 10 files…
+    ///    30% completed
+    ///    Copying “TextEdit”…
+    ///  - note: In swift-corelibs-foundation, Key Value Observing is not yet available.
+    open var localizedDescription: String! {
+        // Unimplemented
+        return ""
+    }
+    
+    /// A more specific description of what progress is being made, fit to present to the user. 
+    ///
+    /// `Progress` is by default KVO-compliant for this property, with the notifications always being sent on thread which updates the property. The default implementation of the getter for this property does not always return the most recently set value of the property. If the most recently set value of this property is nil then `Progress` uses the value of the `kind` property to determine how to use the values of other properties, as well as values in the user info dictionary, to return a computed string. If it fails to do that then it returns an empty string. The difference between this and `localizedDescription` is that this text is meant to be more specific about what work is being done at any particular moment.
+    ///
+    ///   For example, depending on the kind of progress, the completed and total unit counts, and other parameters, these kinds of strings may be generated:
+    ///    3 of 10 files
+    ///    123 KB of 789.1 MB
+    ///    3.3 MB of 103.92 GB — 2 minutes remaining
+    ///    1.61 GB of 3.22 GB (2 KB/sec) — 2 minutes remaining
+    ///    1 minute remaining (1 KB/sec)
+    ///  - note: In swift-corelibs-foundation, Key Value Observing is not yet available.
+    open var localizedAdditionalDescription: String! {
+        // Unimplemented
+        return ""
+    }
+    
+    /// Whether the work being done can be cancelled.
+    ///
+    /// By default `Progress` is cancellable.
+    /// 
+    /// This property is for communicating whether controls for cancelling should appear in a progress reporting user interface. `Progress` itself does not do anything with these properties other than help pass their values from progress reporters to progress observers. It is valid for the values of these properties to change in virtually any way during the lifetime of a `Progress`. Of course, if a `Progress` is cancellable you should actually implement cancellability by setting a cancellation handler or by making your code poll the result of invoking `isCancelled`.
+    open var isCancellable: Bool
+
+    /// Whether the work being done can be paused.
+    ///
+    /// By default `Progress` not pausable.
+    ///
+    /// This property is for communicating whether controls for pausing should appear in a progress reporting user interface. `Progress` itself does not do anything with these properties other than help pass their values from progress reporters to progress observers. It is valid for the values of these properties to change in virtually any way during the lifetime of a `Progress`. Of course, if a `Progress` is pausable you should actually implement pausibility by setting a pausing handler or by making your code poll the result of invoking `isPaused`.
+    open var isPausable: Bool
+    
+    /// Whether the work being done has been cancelled.
+    ///
+    /// Instances of `Progress` that have parents are at least as cancelled as their parents.
+    open var isCancelled: Bool
+
+    /// Whether the work being done has been paused.
+    ///
+    /// Instances of `Progress` that have parents are at least as paused as their parents.
+    open var isPaused: Bool
+    
+    /// A closure to be called when `cancel` is called.
+    ///
+    /// The closure will be called even when the function is called on an ancestor of the receiver. Your closure won't be called on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
+    open var cancellationHandler: (() -> Void)? {
+        didSet {
+            guard let handler = cancellationHandler else { return }
+            // If we're already cancelled, then invoke it - asynchronously
+            if isCancelled {
+                DispatchQueue.global().async {
+                    handler()
+                }
+            }
+        }
+    }
+    
+    /// A closure to be called when pause is called.
+    ///
+    /// The closure will be called even when the function is called on an ancestor of the receiver. Your closure won't be called on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
+    open var pausingHandler: (() -> Void)? {
+        didSet {
+            guard let handler = pausingHandler else { return }
+            // If we're already cancelled, then invoke it - asynchronously
+            if isCancelled {
+                DispatchQueue.global().async {
+                    handler()
+                }
+            }
+        }
+    }
+
+    
+    /// A closure to be called when resume is called.
+    ///
+    /// The closure will be called even when the function is called on an ancestor of the receiver. Your closure won't be called on any particular queue. If it must do work on a specific queue then it should schedule that work on that queue.
+    open var resumingHandler: (() -> Void)?
+    
+    /// Returns `true` if the progress is indeterminate.
+    ///
+    /// This returns `true` when the value of the `totalUnitCount` or `completedUnitCount` property is less than zero. Zero values for both of those properties indicates that there turned out to not be any work to do after all; `isIndeterminate` returns `false` and `fractionCompleted` returns `1.0` in that case.
+    open var isIndeterminate: Bool {
+        return _selfFraction.isIndeterminate
+    }
+    
+    /// Returns `true` if the progress is finished.
+    ///
+    /// Checking the result of this function is preferred to comparing `fractionCompleted`, as rounding errors can cause that value to appear less than `1.0` in some circumstances.
+    /// - Experiment: This is a draft API currently under consideration for official import into Foundation
+    open var isFinished: Bool {
+        return _selfFraction.isFinished
+    }
+    
+    /// The fraction of the overall work completed by this progress object, including work done by any children it may have.
+    public var fractionCompleted: Double {
+        // We have to special case one thing to maintain consistency; if _selfFraction.total == 0 then we do not add any children
+        guard _selfFraction.total > 0 else { return _selfFraction.fractionCompleted }
+        return (_selfFraction + _childFraction).fractionCompleted
+    }
+    
+    /// Calls the closure registered with the `cancellationHandler` property, if there is one, and set the `isCancelled` property to `true`.
+    ///
+    /// Do this for this `Progress` and any descendants of this `Progress`.
+    open func cancel() {
+        isCancelled = true
+        
+        if let handler = cancellationHandler {
+            DispatchQueue.global().async {
+                handler()
+            }
+        }
+        
+        for child in _children {
+            child.cancel()
+        }
+    }
+    
+    /// Calls the closure registered with the `pausingHandler` property, if there is one, and set the `isPaused` property to `true`.
+    ///
+    /// Do this for this `Progress` and any descendants of this `Progress`.
+    open func pause() {
+        isPaused = true
+        
+        if let handler = pausingHandler {
+            DispatchQueue.global().async {
+                handler()
+            }
+        }
+        
+        for child in _children {
+            child.pause()
+        }
+    }
+    
+    /// Calls the closure registered with the `resumingHandler` property, if there is one, and set the `isPaused` property to `false`.
+    ///
+    /// Do this for this `Progress` and any descendants of this `Progress`.
+    open func resume() {
+        isPaused = false
+        
+        if let handler = resumingHandler {
+            DispatchQueue.global().async {
+                handler()
+            }
+        }
+        
+        for child in _children {
+            child.resume()
+        }
+    }
+    
+    /// Set a value in the dictionary returned by `userInfo`, with appropriate KVO notification for properties whose values can depend on values in the user info dictionary, like `localizedDescription`. If a nil value is passed then the dictionary entry is removed.
+    /// - note: In swift-corelibs-foundation, Key Value Observing is not yet available.
+    open func setUserInfoObject(_ objectOrNil: Any?, forKey key: ProgressUserInfoKey) {
+        _userInfo[key] = objectOrNil
+    }
+    
+    /// A collection of arbitrary values associated with this `Progress`. 
+    ///
+    /// Returns a KVO-compliant dictionary that changes as `setUserInfoObject(forKey:)` is sent to this `Progress`. The dictionary will send all of its KVO notifications on the thread which updates the property. The result will never be nil, but may be an empty dictionary.
+    ///
+    /// Some entries have meanings that are recognized by the `Progress` class itself. See also `ProgressUserInfoKey`.
+    /// - note: In swift-corelibs-foundation, Key Value Observing is not yet available.
+    open var userInfo: [ProgressUserInfoKey : Any] {
+        return _userInfo
+    }
+
+    /// Optionally specifies more information about what kind of progress is being reported.
+    ///
+    /// If the value of the `localizedDescription` property has not been set, then the default implementation of `localizedDescription` uses the progress kind to determine how to use the values of other properties, as well as values in the user info dictionary, to create a string that is presentable to the user.
+    open var kind: ProgressKind?
+    
+    public struct FileOperationKind : RawRepresentable, Equatable, Hashable, Comparable {
+        public let rawValue: String
+        public init(_ rawValue: String) { self.rawValue = rawValue }
+        public init(rawValue: String) { self.rawValue = rawValue }
+        public var hashValue: Int { return self.rawValue.hashValue }
+        public static func ==(_ lhs: FileOperationKind, _ rhs: FileOperationKind) -> Bool { return lhs.rawValue == rhs.rawValue }
+        public static func <(_ lhs: FileOperationKind, _ rhs: FileOperationKind) -> Bool { return lhs.rawValue < rhs.rawValue }
+        
+        /// Use for indicating the progress represents a download.
+        public static let downloading = FileOperationKind(rawValue: "NSProgressFileOperationKindDownloading")
+
+        /// Use for indicating the progress represents decompressing after downloading.
+        public static let decompressingAfterDownloading = FileOperationKind(rawValue: "NSProgressFileOperationKindDecompressingAfterDownloading")
+        
+        /// Use for indicating the progress represents receiving a file in some way.
+        public static let receiving = FileOperationKind(rawValue: "NSProgressFileOperationKindReceiving")
+        
+        /// Use for indicating the progress represents copying a file.
+        public static let copying = FileOperationKind(rawValue: "NSProgressFileOperationKindCopying")
+    }
+    
+    // MARK: -
+    // MARK: Implementation of unit counts
+    
+    private var _overallFraction : _ProgressFraction {
+        return _selfFraction + _childFraction
+    }
+    
+    private func _addCompletedUnitCount(_ unitCount : Int64) {
+        let old = _overallFraction
+        _selfFraction.completed += unitCount
+        let new = _overallFraction
+        _updateFractionCompleted(from: old, to: new)
+    }
+
+    private func _updateFractionCompleted(from: _ProgressFraction, to: _ProgressFraction) {
+        if from != to {
+            _parent?._updateChild(self, from: from, to: to, portion: _portionOfParent)
+        }
+    }
+    
+    /// A child progress has been updated, which changes our own fraction completed.
+    private func _updateChild(_ child: Progress, from previous: _ProgressFraction, to next: _ProgressFraction, portion: Int64) {
+        let previousOverallFraction = _overallFraction
+        
+        let multiple = _ProgressFraction(completed: portion, total: _selfFraction.total)
+        let oldFractionOfParent = previous * multiple
+        
+        // Subtract the previous fraction (multiplied by portion), add new fraction (multiplied by portion). If either is indeterminate, treat as zero.
+        if !previous.isIndeterminate {
+            _childFraction = _childFraction - oldFractionOfParent
+        }
+        
+        if !next.isIndeterminate {
+            _childFraction = _childFraction + (next * multiple)
+        }
+        
+        if next.isFinished {
+            _children.remove(child)
+            
+            if portion != 0 {
+                // Update our self completed units
+                _selfFraction.completed += portion
+                
+                // Subtract the (child's fraction completed * multiple) from our child fraction
+                _childFraction = _childFraction - (multiple * next)
+            }
+        }
+        
+        _updateFractionCompleted(from: previousOverallFraction, to: _overallFraction)
+    }
+}
+
+/// If your class supports reporting progress, then you can adopt the ProgressReporting protocol. 
+///
+/// Objects that adopt this protocol should typically be "one-shot" -- that is, the progress is setup at initialization of the object and is updated when work is done. The value of the property should not be set to another progress object. Instead, the user of the `ProgressReporting` class should create a new instance to represent a new set of work.
+public protocol ProgressReporting : NSObjectProtocol {
+    var progress: Progress { get }
+}
+
+public struct ProgressKind : RawRepresentable, Equatable, Hashable, Comparable {
+    public let rawValue: String
+    public init(_ rawValue: String) { self.rawValue = rawValue }
+    public init(rawValue: String) { self.rawValue = rawValue }
+    public var hashValue: Int { return self.rawValue.hashValue }
+    public static func ==(_ lhs: ProgressKind, _ rhs: ProgressKind) -> Bool { return lhs.rawValue == rhs.rawValue }
+    public static func <(_ lhs: ProgressKind, _ rhs: ProgressKind) -> Bool { return lhs.rawValue < rhs.rawValue }
+    
+    /// Indicates that the progress being performed is related to files.
+    ///
+    /// Progress of this kind is assumed to use bytes as the unit of work being done and the default implementation of `localizedDescription` takes advantage of that to return more specific text than it could otherwise.
+    public static let file = ProgressKind(rawValue: "NSProgressKindFile")
+}
+
+public struct ProgressUserInfoKey : RawRepresentable, Equatable, Hashable, Comparable {
+    public let rawValue: String
+    public init(_ rawValue: String) { self.rawValue = rawValue }
+    public init(rawValue: String) { self.rawValue = rawValue }
+    public var hashValue: Int { return self.rawValue.hashValue }
+    public static func ==(_ lhs: ProgressUserInfoKey, _ rhs: ProgressUserInfoKey) -> Bool { return lhs.rawValue == rhs.rawValue }
+    public static func <(_ lhs: ProgressUserInfoKey, _ rhs: ProgressUserInfoKey) -> Bool { return lhs.rawValue < rhs.rawValue }
+    
+    /// How much time is probably left in the operation, as an NSNumber containing a number of seconds.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is an `NSNumber`.
+    public static let estimatedTimeRemainingKey = ProgressUserInfoKey(rawValue: "NSProgressEstimatedTimeRemainingKey")
+    
+    /// How fast data is being processed, as an NSNumber containing bytes per second.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is an `NSNumber`.
+    public static let throughputKey = ProgressUserInfoKey(rawValue: "NSProgressThroughputKey")
+    
+    /// A description of what "kind" of progress is being made on a file.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is a `Progress.FileOperationKind`.
+    public static let fileOperationKindKey = ProgressUserInfoKey(rawValue: "NSProgressFileOperationKindKey")
+    
+    /// A URL for the item on which progress is being made.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is a `URL`.
+    public static let fileURLKey = ProgressUserInfoKey(rawValue: "NSProgressFileURLKey")
+    
+    /// The total number of files.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is an `NSNumber`.
+    public static let fileTotalCountKey = ProgressUserInfoKey(rawValue: "NSProgressFileTotalCountKey")
+
+    /// The completed number of files.
+    ///
+    /// If this value is present, then `Progress` can present a more detailed `localizedAdditionalDescription`.
+    /// Value is an `NSNumber`.
+    public static let fileCompletedCountKey = ProgressUserInfoKey(rawValue: "NSProgressFileCompletedCountKey")
+}
+
+fileprivate class _ProgressTSD {
+    /// The thread's default progress.
+    fileprivate var currentProgress : Progress
+    
+    /// The instances of this thing that will become current the next time resignCurrent is called
+    fileprivate var nextTSD : _ProgressTSD?
+    
+    /// Pending unit count
+    var pendingUnitCount : Int64
+    
+    /// True if any children are implicitly attached
+    var childAttached : Bool
+    
+    init(currentProgress: Progress, nextTSD: _ProgressTSD?, pendingUnitCount: Int64) {
+        self.currentProgress = currentProgress
+        self.pendingUnitCount = pendingUnitCount
+        self.nextTSD = nextTSD
+        childAttached = false
+    }
+}
diff --git a/Foundation/ProgressFraction.swift b/Foundation/ProgressFraction.swift
new file mode 100644
index 0000000..8fcf3de
--- /dev/null
+++ b/Foundation/ProgressFraction.swift
@@ -0,0 +1,276 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+// Implementation note: This file is included in both the framework and the test bundle, in order for us to be able to test it directly. Once @testable support works for Linux we may be able to use it from the framework instead.
+
+internal struct _ProgressFraction : Equatable, CustomDebugStringConvertible {
+    var completed : Int64
+    var total : Int64
+    private(set) var overflowed : Bool
+    
+    init() {
+        completed = 0
+        total = 0
+        overflowed = false
+    }
+    
+    init(double: Double, overflow: Bool = false) {
+        if double == 0 {
+            self.completed = 0
+            self.total = 1
+        } else if double == 1 {
+            self.completed = 1
+            self.total = 1
+        }
+        
+        (self.completed, self.total) = _ProgressFraction._fromDouble(double)
+        self.overflowed = overflow
+    }
+    
+    init(completed: Int64, total: Int64) {
+        self.completed = completed
+        self.total = total
+        self.overflowed = false
+    }
+    
+    // ----
+    
+    internal mutating func simplify() {
+        if self.total == 0 {
+            return
+        }
+        
+        (self.completed, self.total) = _ProgressFraction._simplify(completed, total)
+    }
+    
+    internal func simplified() -> _ProgressFraction {
+        let simplified = _ProgressFraction._simplify(completed, total)
+        return _ProgressFraction(completed: simplified.0, total: simplified.1)
+    }
+    
+    static private func _math(lhs: _ProgressFraction, rhs: _ProgressFraction, whichOperator: (_ lhs : Double, _ rhs : Double) -> Double, whichOverflow : (_ lhs: Int64, _ rhs: Int64) -> (Int64, overflow: Bool)) -> _ProgressFraction {
+        // Mathematically, it is nonsense to add or subtract something with a denominator of 0. However, for the purposes of implementing Progress' fractions, we just assume that a zero-denominator fraction is "weightless" and return the other value. We still need to check for the case where they are both nonsense though.
+        precondition(!(lhs.total == 0 && rhs.total == 0), "Attempt to add or subtract invalid fraction")
+        guard lhs.total != 0 else {
+            return rhs
+        }
+        guard rhs.total != 0 else {
+            return lhs
+        }
+        
+        guard !lhs.overflowed && !rhs.overflowed else {
+            // If either has overflowed already, we preserve that
+            return _ProgressFraction(double: whichOperator(lhs.fractionCompleted, rhs.fractionCompleted), overflow: true)
+        }
+
+        if let lcm = _leastCommonMultiple(lhs.total, rhs.total) {
+            let result = whichOverflow(lhs.completed * (lcm / lhs.total), rhs.completed * (lcm / rhs.total))
+            if result.overflow {
+                return _ProgressFraction(double: whichOperator(lhs.fractionCompleted, rhs.fractionCompleted), overflow: true)
+            } else {
+                return _ProgressFraction(completed: result.0, total: lcm)
+            }
+        } else {
+            // Overflow - simplify and then try again
+            let lhsSimplified = lhs.simplified()
+            let rhsSimplified = rhs.simplified()
+            
+            if let lcm = _leastCommonMultiple(lhsSimplified.total, rhsSimplified.total) {
+                let result = whichOverflow(lhsSimplified.completed * (lcm / lhsSimplified.total), rhsSimplified.completed * (lcm / rhsSimplified.total))
+                if result.overflow {
+                    // Use original lhs/rhs here
+                    return _ProgressFraction(double: whichOperator(lhs.fractionCompleted, rhs.fractionCompleted), overflow: true)
+                } else {
+                    return _ProgressFraction(completed: result.0, total: lcm)
+                }
+            } else {
+                // Still overflow
+                return _ProgressFraction(double: whichOperator(lhs.fractionCompleted, rhs.fractionCompleted), overflow: true)
+            }
+        }
+    }
+    
+    static internal func +(lhs: _ProgressFraction, rhs: _ProgressFraction) -> _ProgressFraction {
+        return _math(lhs: lhs, rhs: rhs, whichOperator: +, whichOverflow: Int64.addWithOverflow)
+    }
+    
+    static internal func -(lhs: _ProgressFraction, rhs: _ProgressFraction) -> _ProgressFraction {
+        return _math(lhs: lhs, rhs: rhs, whichOperator: -, whichOverflow: Int64.subtractWithOverflow)
+    }
+    
+    static internal func *(lhs: _ProgressFraction, rhs: _ProgressFraction) -> _ProgressFraction {
+        guard !lhs.overflowed && !rhs.overflowed else {
+            // If either has overflowed already, we preserve that
+            return _ProgressFraction(double: rhs.fractionCompleted * rhs.fractionCompleted, overflow: true)
+        }
+
+        let newCompleted = Int64.multiplyWithOverflow(lhs.completed, rhs.completed)
+        let newTotal = Int64.multiplyWithOverflow(lhs.total, rhs.total)
+        
+        if newCompleted.overflow || newTotal.overflow {
+            // Try simplifying, then do it again
+            let lhsSimplified = lhs.simplified()
+            let rhsSimplified = rhs.simplified()
+            
+            let newCompletedSimplified = Int64.multiplyWithOverflow(lhsSimplified.completed, rhsSimplified.completed)
+            let newTotalSimplified = Int64.multiplyWithOverflow(lhsSimplified.total, rhsSimplified.total)
+            
+            if newCompletedSimplified.overflow || newTotalSimplified.overflow {
+                // Still overflow
+                return _ProgressFraction(double: lhs.fractionCompleted * rhs.fractionCompleted, overflow: true)
+            } else {
+                return _ProgressFraction(completed: newCompletedSimplified.0, total: newTotalSimplified.0)
+            }
+        } else {
+            return _ProgressFraction(completed: newCompleted.0, total: newTotal.0)
+        }
+    }
+    
+    static internal func /(lhs: _ProgressFraction, rhs: Int64) -> _ProgressFraction {
+        guard !lhs.overflowed else {
+            // If lhs has overflowed, we preserve that
+            return _ProgressFraction(double: lhs.fractionCompleted / Double(rhs), overflow: true)
+        }
+        
+        let newTotal = Int64.multiplyWithOverflow(lhs.total, rhs)
+        
+        if newTotal.overflow {
+            let simplified = lhs.simplified()
+            
+            let newTotalSimplified = Int64.multiplyWithOverflow(simplified.total, rhs)
+            
+            if newTotalSimplified.overflow {
+                // Still overflow
+                return _ProgressFraction(double: lhs.fractionCompleted / Double(rhs), overflow: true)
+            } else {
+                return _ProgressFraction(completed: lhs.completed, total: newTotalSimplified.0)
+            }
+        } else {
+            return _ProgressFraction(completed: lhs.completed, total: newTotal.0)
+        }
+    }
+    
+    static internal func ==(lhs: _ProgressFraction, rhs: _ProgressFraction) -> Bool {
+        if lhs.isNaN || rhs.isNaN {
+            // NaN fractions are never equal
+            return false
+        } else if lhs.completed == rhs.completed && lhs.total == rhs.total {
+            return true
+        } else if lhs.total == rhs.total {
+            // Direct comparison of numerator
+            return lhs.completed == rhs.completed
+        } else if lhs.completed == 0 && rhs.completed == 0 {
+            return true
+        } else if lhs.completed == lhs.total && rhs.completed == rhs.total {
+            // Both finished (1)
+            return true
+        } else if (lhs.completed == 0 && rhs.completed != 0) || (lhs.completed != 0 && rhs.completed == 0) {
+            // One 0, one not 0
+            return false
+        } else {
+            // Cross-multiply
+            let left = Int64.multiplyWithOverflow(lhs.completed, rhs.total)
+            let right = Int64.multiplyWithOverflow(lhs.total, rhs.completed)
+            
+            if !left.overflow && !right.overflow {
+                if left.0 == right.0 {
+                    return true
+                }
+            } else {
+                // Try simplifying then cross multiply again
+                let lhsSimplified = lhs.simplified()
+                let rhsSimplified = rhs.simplified()
+                
+                let leftSimplified = Int64.multiplyWithOverflow(lhsSimplified.completed, rhsSimplified.total)
+                let rightSimplified = Int64.multiplyWithOverflow(lhsSimplified.total, rhsSimplified.completed)
+
+                if !leftSimplified.overflow && !rightSimplified.overflow {
+                    if leftSimplified.0 == rightSimplified.0 {
+                        return true
+                    }
+                } else {
+                    // Ok... fallback to doubles. This doesn't use an epsilon
+                    return lhs.fractionCompleted == rhs.fractionCompleted
+                }
+            }
+        }
+        
+        return false
+    }
+    
+    // ----
+    
+    internal var isIndeterminate : Bool {
+        return completed < 0 || total < 0 || (completed == 0 && total == 0)
+    }
+    
+    internal var isFinished : Bool {
+        return ((completed >= total) && completed > 0 && total > 0) || (completed > 0 && total == 0)
+    }
+    
+    internal var fractionCompleted : Double {
+        if isIndeterminate {
+            // Return something predictable
+            return 0.0
+        } else if total == 0 {
+            // When there is nothing to do, you're always done
+            return 1.0
+        } else {
+            return Double(completed) / Double(total)
+        }
+    }
+    
+    internal var isNaN : Bool {
+        return total == 0
+    }
+    
+    internal var debugDescription : String {
+        return "\(completed) / \(total) (\(fractionCompleted))"
+    }
+    
+    // ----
+    
+    private static func _fromDouble(_ d : Double) -> (Int64, Int64) {
+        // This simplistic algorithm could someday be replaced with something better.
+        // Basically - how many 1/Nths is this double?
+        // And we choose to use 131072 for N
+        let denominator : Int64 = 131072
+        let numerator = Int64(d / (1.0 / Double(denominator)))
+        return (numerator, denominator)
+    }
+    
+    private static func _greatestCommonDivisor(_ inA : Int64, _ inB : Int64) -> Int64 {
+        // This is Euclid's algorithm. There are faster ones, like Knuth, but this is the simplest one for now.
+        var a = inA
+        var b = inB
+        repeat {
+            let tmp = b
+            b = a % b
+            a = tmp
+        } while (b != 0)
+        return a
+    }
+    
+    private static func _leastCommonMultiple(_ a : Int64, _ b : Int64) -> Int64? {
+        // This division always results in an integer value because gcd(a,b) is a divisor of a.
+        // lcm(a,b) == (|a|/gcd(a,b))*b == (|b|/gcd(a,b))*a
+        let result = Int64.multiplyWithOverflow((a / _greatestCommonDivisor(a, b)), b)
+        if result.overflow {
+            return nil
+        } else {
+            return result.0
+        }
+    }
+    
+    private static func _simplify(_ n : Int64, _ d : Int64) -> (Int64, Int64) {
+        let gcd = _greatestCommonDivisor(n, d)
+        return (n / gcd, d / gcd)
+    }
+    
+}
diff --git a/TestFoundation/TestNSProgressFraction.swift b/TestFoundation/TestNSProgressFraction.swift
new file mode 100644
index 0000000..0e42e90
--- /dev/null
+++ b/TestFoundation/TestNSProgressFraction.swift
@@ -0,0 +1,162 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+import Foundation
+import XCTest
+#else
+import SwiftFoundation
+import SwiftXCTest
+#endif
+
+class TestProgressFraction : XCTestCase {
+    static var allTests: [(String, (TestProgressFraction) -> () throws -> Void)] {
+        return [
+            ("test_equal", test_equal ),
+            ("test_subtract", test_subtract),
+            ("test_multiply", test_multiply),
+            ("test_simplify", test_simplify),
+            ("test_overflow", test_overflow),
+            ("test_addOverflow", test_addOverflow),
+            ("test_andAndSubtractOverflow", test_andAndSubtractOverflow),
+            ("test_fractionFromDouble", test_fractionFromDouble),
+            ("test_unnecessaryOverflow", test_unnecessaryOverflow),
+        ]
+    }
+
+    func test_equal() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 100, total: 200)
+        
+        XCTAssertEqual(f1, f2)
+        
+        let f3 = _ProgressFraction(completed: 3, total: 10)
+        XCTAssertNotEqual(f1, f3)
+        
+        let f4 = _ProgressFraction(completed: 5, total: 10)
+        XCTAssertEqual(f1, f4)
+    }
+    
+    func test_addSame() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 3, total: 10)
+
+        let r = f1 + f2
+        XCTAssertEqual(r.completed, 8)
+        XCTAssertEqual(r.total, 10)
+    }
+    
+    func test_addDifferent() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 300, total: 1000)
+
+        let r = f1 + f2
+        XCTAssertEqual(r.completed, 800)
+        XCTAssertEqual(r.total, 1000)
+    }
+    
+    func test_subtract() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 3, total: 10)
+
+        let r = f1 - f2
+        XCTAssertEqual(r.completed, 2)
+        XCTAssertEqual(r.total, 10)
+    }
+    
+    func test_multiply() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 1, total: 2)
+
+        let r = f1 * f2
+        XCTAssertEqual(r.completed, 5)
+        XCTAssertEqual(r.total, 20)
+    }
+    
+    func test_simplify() {
+        let f1 = _ProgressFraction(completed: 5, total: 10)
+        let f2 = _ProgressFraction(completed: 3, total: 10)
+
+        let r = (f1 + f2).simplified()
+        
+        XCTAssertEqual(r.completed, 4)
+        XCTAssertEqual(r.total, 5)
+    }
+    
+    func test_overflow() {
+        // These prime numbers are problematic for overflowing
+        let denominators : [Int64] = [5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 69]
+        
+        var f1 = _ProgressFraction(completed: 1, total: 3)
+        for d in denominators {
+            f1 = f1 + _ProgressFraction(completed: 1, total: d)
+        }
+        
+        let fractionResult = f1.fractionCompleted
+        var expectedResult = 1.0 / 3.0
+        for d in denominators {
+            expectedResult = expectedResult + 1.0 / Double(d)
+        }
+        
+        XCTAssertEqualWithAccuracy(fractionResult, expectedResult, accuracy: 0.00001)
+    }
+    
+    func test_addOverflow() {
+        // These prime numbers are problematic for overflowing
+        let denominators : [Int64] = [5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 69]
+        var f1 = _ProgressFraction(completed: 1, total: 3)
+        for d in denominators {
+            f1 = f1 + _ProgressFraction(completed: 1, total: d)
+        }
+
+        // f1 should be in overflow
+        XCTAssertTrue(f1.overflowed)
+        
+        let f2 = _ProgressFraction(completed: 1, total: 4) + f1
+        
+        // f2 should also be in overflow
+        XCTAssertTrue(f2.overflowed)
+        
+        // And it should have completed value of about 1.0/4.0 + f1.fractionCompleted
+        let expected = (1.0 / 4.0) + f1.fractionCompleted
+        
+        XCTAssertEqualWithAccuracy(expected, f2.fractionCompleted, accuracy: 0.00001)
+    }
+    
+    func test_andAndSubtractOverflow() {
+        let f1 = _ProgressFraction(completed: 48, total: 60)
+        let f2 = _ProgressFraction(completed: 5880, total: 7200)
+        let f3 = _ProgressFraction(completed: 7048893638467736640, total: 8811117048084670800)
+        
+        let result1 = (f3 - f1) + f2
+        XCTAssertTrue(result1.completed > 0)
+        
+        let result2 = (f3 - f2) + f1
+        XCTAssertTrue(result2.completed < 60)
+    }
+    
+    func test_fractionFromDouble() {
+        let d = 4.25 // exactly representable in binary
+        let f1 = _ProgressFraction(double: d)
+        
+        let simplified = f1.simplified()
+        XCTAssertEqual(simplified.completed, 17)
+        XCTAssertEqual(simplified.total, 4)
+    }
+    
+    func test_unnecessaryOverflow() {
+        // just because a fraction has a large denominator doesn't mean it needs to overflow
+        let f1 = _ProgressFraction(completed: (Int64.max - 1) / 2, total: Int64.max - 1)
+        let f2 = _ProgressFraction(completed: 1, total: 16)
+        
+        let r = f1 + f2
+        XCTAssertFalse(r.overflowed)
+    }
+}
+
diff --git a/TestFoundation/TestProgress.swift b/TestFoundation/TestProgress.swift
new file mode 100644
index 0000000..797058f
--- /dev/null
+++ b/TestFoundation/TestProgress.swift
@@ -0,0 +1,412 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
+import Foundation
+import XCTest
+#else
+import SwiftFoundation
+import SwiftXCTest
+#endif
+
+import Dispatch
+
+class TestProgress : XCTestCase {
+    static var allTests: [(String, (TestProgress) -> () throws -> Void)] {
+        return [
+            ("test_totalCompletedChangeAffectsFractionCompleted", test_totalCompletedChangeAffectsFractionCompleted),
+            ("test_multipleChildren", test_multipleChildren),
+            ("test_indeterminateChildrenAffectFractionCompleted", test_indeterminateChildrenAffectFractionCompleted),
+            ("test_indeterminateChildrenAffectFractionCompleted2", test_indeterminateChildrenAffectFractionCompleted2),
+            ("test_childCompletionFinishesGroups", test_childCompletionFinishesGroups),
+            ("test_childrenAffectFractionCompleted_explicit", test_childrenAffectFractionCompleted_explicit),
+            ("test_childrenAffectFractionCompleted_explicit_partial", test_childrenAffectFractionCompleted_explicit_partial),
+            ("test_childrenAffectFractionCompleted_explicit_child_already_complete", test_childrenAffectFractionCompleted_explicit_child_already_complete),
+            ("test_grandchildrenAffectFractionCompleted", test_grandchildrenAffectFractionCompleted),
+            ("test_grandchildrenAffectFractionCompleted_explicit", test_grandchildrenAffectFractionCompleted_explicit),
+            ("test_mixedExplicitAndImplicitChildren", test_mixedExplicitAndImplicitChildren),
+            ("test_notReturningNaN", test_notReturningNaN),
+            ("test_handlers", test_handlers),
+            ("test_alreadyCancelled", test_alreadyCancelled),
+            ("test_userInfo", test_userInfo),
+        ]
+    }
+    
+    func test_totalCompletedChangeAffectsFractionCompleted() {
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 100
+        
+        // Test self
+        parent.completedUnitCount = 50
+        XCTAssertEqualWithAccuracy(0.5, parent.fractionCompleted, accuracy: 0.01)
+        
+        parent.completedUnitCount = 0
+        // Test child
+        parent.becomeCurrent(withPendingUnitCount: 10)
+        let child1 = Progress(totalUnitCount: 100)
+        child1.completedUnitCount = 50
+        
+        // half of 10% is done in parent
+        XCTAssertEqualWithAccuracy(0.05, parent.fractionCompleted, accuracy: 0.01)
+        XCTAssertEqualWithAccuracy(0.5, child1.fractionCompleted, accuracy: 0.01)
+        
+        // Up the total amount of work
+        parent.totalUnitCount = 200
+        
+        XCTAssertEqualWithAccuracy(0.5 * (10.0 / 200.0) /* 0.025 */, parent.fractionCompleted, accuracy: 0.01)
+        XCTAssertEqualWithAccuracy(0.5, child1.fractionCompleted, accuracy: 0.01)
+        
+        // Change the total in the child, doubling total amount of work
+        child1.totalUnitCount = 200
+        XCTAssertEqualWithAccuracy(50.0 / 200.0, child1.fractionCompleted, accuracy: 0.01)
+        XCTAssertEqualWithAccuracy((50.0 / 200.0) * (10.0 / 200), parent.fractionCompleted, accuracy: 0.01)
+        
+        // Change the total in the child, the other direction, halving the amount of work
+        child1.totalUnitCount = 100
+        XCTAssertEqualWithAccuracy(50.0 / 100.0, child1.fractionCompleted, accuracy: 0.01)
+        XCTAssertEqualWithAccuracy((50.0 / 100.0) * (10.0 / 200), parent.fractionCompleted, accuracy: 0.01)
+    }
+    
+    func test_multipleChildren() {
+        // Verify that when multiple children are added to one group, they do the right thing
+        // n.b. prior to 10.11 / 9.0, this split up the pending unit among all of the children. After that, we give all of the pending unit count to the first child. This is because if you split up the pending unit count, the progress will almost certainly go backwards. API was added to give more explicit control over adding multiple children.
+        let progress = Progress(parent: nil)
+        progress.totalUnitCount = 100
+        
+        // Create two children
+        progress.becomeCurrent(withPendingUnitCount: 100)
+        let child1 = Progress(totalUnitCount: 5)
+        let child2 = Progress(totalUnitCount: 5)
+        
+        XCTAssertEqualWithAccuracy(progress.fractionCompleted, 0, accuracy: 0.01)
+        
+        child2.completedUnitCount = 5
+        
+        // Child2 does not affect the parent's fraction completed (it should only be child1 that makes a difference)
+        XCTAssertEqualWithAccuracy(progress.fractionCompleted, 0, accuracy: 0.01)
+
+        let _ = Progress(totalUnitCount: 5)
+        XCTAssertEqualWithAccuracy(progress.fractionCompleted, 0, accuracy: 0.01)
+        
+        // Update child #1
+        child1.completedUnitCount = 5
+        XCTAssertEqualWithAccuracy(progress.fractionCompleted, 1.0, accuracy: 0.01)
+    }
+    
+    func test_indeterminateChildrenAffectFractionCompleted() {
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 1000
+        
+        parent.becomeCurrent(withPendingUnitCount: 100)
+        let child1 = Progress(totalUnitCount: 10)
+        
+        child1.completedUnitCount = 5
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.05, accuracy: 0.01)
+        
+        // Child1 becomes indeterminate
+        child1.completedUnitCount = -1
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.0, accuracy: 0.01)
+        
+        // Become determinate
+        // childProgress1's completed unit count is 100% of its total of 10 (10)
+        // childProgress1 is 10% of the overall unit count (100 / 1000)
+        // the overall count done should be 100% of 10% of 1000, or 1.0 * 0.1 * 1000 = 100
+        // the overall percentage done should be 100 / 1000 = 0.1
+        child1.completedUnitCount = 10
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.1, accuracy: 0.01)
+        
+        // Become indeterminate again
+        child1.completedUnitCount = -1
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.0, accuracy: 0.01)
+        
+        parent.resignCurrent()
+    }
+
+    func test_indeterminateChildrenAffectFractionCompleted2() {
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 100
+        
+        parent.becomeCurrent(withPendingUnitCount: 50)
+        let child1 = Progress(totalUnitCount: 2)
+        parent.resignCurrent()
+
+        parent.becomeCurrent(withPendingUnitCount: 50)
+        let child2 = Progress(totalUnitCount: 2)
+        parent.resignCurrent()
+
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.0, accuracy: 0.01)
+
+        child1.completedUnitCount = 1
+        child2.completedUnitCount = 1
+        
+        // half done
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.5, accuracy: 0.01)
+        
+        // Move a child to indeterminate
+        child1.completedUnitCount = -1
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.25, accuracy: 0.01)
+        
+        // Move it back to determinate
+        child1.completedUnitCount = 1
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 0.5, accuracy: 0.01)
+    }
+
+    func test_childCompletionFinishesGroups() {
+        let root = Progress(totalUnitCount: 2)
+        let child1 = Progress(totalUnitCount: 1)
+        let child2 = Progress(totalUnitCount: 1)
+        
+        root.addChild(child1, withPendingUnitCount: 1)
+        root.addChild(child2, withPendingUnitCount: 1)
+        
+        child1.completedUnitCount = 1
+        XCTAssertEqualWithAccuracy(root.fractionCompleted, 0.5, accuracy: 0.01)
+        
+        child2.completedUnitCount = 1
+        XCTAssertEqualWithAccuracy(root.fractionCompleted, 1.0, accuracy: 0.01)
+        XCTAssertEqual(root.completedUnitCount, 2)
+    }
+    
+    func test_childrenAffectFractionCompleted_explicit() {
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 100
+        
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+        
+        let child1 = Progress(totalUnitCount: 100)
+        parent.addChild(child1, withPendingUnitCount: 10)
+        
+        child1.completedUnitCount = 50
+        
+        // let's say some of this work is done inside the become/resign pair
+        // half of 10% is done
+        XCTAssertEqual(0.05, parent.fractionCompleted)
+        
+        // ... and the rest is done outside the become/resign pair
+        child1.completedUnitCount = 100;
+        
+        // Now the rest is done
+        XCTAssertEqual(0.10, parent.fractionCompleted)
+        
+        // Add another child
+        let child2 = Progress(totalUnitCount: 100)
+        parent.addChild(child2, withPendingUnitCount: 90)
+        child2.completedUnitCount = 50
+        
+        XCTAssertEqual(0.10 + 0.9 / 2.0, parent.fractionCompleted)
+    }
+    
+    func test_childrenAffectFractionCompleted_explicit_partial() {
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 2
+        
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+        
+        // Add a child, then update after adding
+        let child1 = Progress(totalUnitCount: 100)
+        parent.addChild(child1, withPendingUnitCount: 1)
+        child1.completedUnitCount = 50
+        
+        // Half of 50% is done
+        XCTAssertEqual(0.25, parent.fractionCompleted)
+        
+        // Add a new child, but it is already in process
+        let child2 = Progress(totalUnitCount: 100)
+        child2.completedUnitCount = 50
+        parent.addChild(child2, withPendingUnitCount: 1)
+        
+        // half of 50% is done + half of 50% is done == 50% of overall work is done
+        XCTAssertEqual(0.50, parent.fractionCompleted)
+    }
+    
+    func test_childrenAffectFractionCompleted_explicit_child_already_complete() {
+        // Adding children who are already partially completed should cause the parent fraction completed to be updated
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 2
+        
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+        
+        // Add a child, then update after adding
+        let child1 = Progress(totalUnitCount: 100)
+        child1.completedUnitCount = 100
+        parent.addChild(child1, withPendingUnitCount: 1)
+        
+        // all of 50% is done
+        XCTAssertEqual(0.5, parent.fractionCompleted)
+    }
+    
+    func test_grandchildrenAffectFractionCompleted_explicit() {
+        // The parent's progress is entirely represented by the 1 grandchild
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 100
+        
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+
+        let child = Progress(totalUnitCount: 100)
+        parent.addChild(child, withPendingUnitCount: 100)
+        
+        let grandchild = Progress(totalUnitCount: 100)
+        child.addChild(grandchild, withPendingUnitCount: 100)
+        
+        // Now we have parentProgress <- childProgress <- grandchildProgress
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+
+        grandchild.completedUnitCount = 50
+        
+        XCTAssertEqual(0.50, parent.fractionCompleted)
+    }
+    
+    func test_grandchildrenAffectFractionCompleted() {
+        // The parent's progress is entirely represented by the 1 grandchild
+        let parent = Progress(parent: nil)
+        parent.totalUnitCount = 100
+        
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+        
+        parent.becomeCurrent(withPendingUnitCount: 100)
+        let child = Progress(totalUnitCount: 100)
+        parent.resignCurrent()
+        
+        child.becomeCurrent(withPendingUnitCount: 100)
+        let grandchild = Progress(totalUnitCount: 100)
+        child.resignCurrent()
+        
+        // Now we have parentProgress <- childProgress <- grandchildProgress
+        XCTAssertEqual(parent.fractionCompleted, 0.0)
+        
+        grandchild.completedUnitCount = 50
+        XCTAssertEqual(0.50, parent.fractionCompleted)
+    }
+
+    func test_mixedExplicitAndImplicitChildren() {
+        let parent = Progress(parent: nil)
+        
+        parent.totalUnitCount = 3
+        
+        let child1 = Progress(totalUnitCount: 10)
+        let child2 = Progress(totalUnitCount: 10)
+        parent.addChild(child1, withPendingUnitCount: 1)
+        parent.addChild(child2, withPendingUnitCount: 1)
+        
+        // child1 is half done. This means the parent is half of 1/3 done.
+        child1.completedUnitCount = 5
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, (1.0 / 3.0) / 2.0, accuracy: 0.01)
+        
+        // child2 is half done. This means the parent is (half of 1/3 done) + (half of 1/3 done).
+        child2.completedUnitCount = 5
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, ((1.0 / 3.0) / 2.0) * 2.0, accuracy: 0.01)
+        
+        // add an implict child
+        parent.becomeCurrent(withPendingUnitCount: 1)
+        let child3 = Progress(totalUnitCount: 10)
+        parent.resignCurrent()
+        
+        // Total completed of parent should not change
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, ((1.0 / 3.0) / 2.0) * 2.0, accuracy: 0.01)
+        
+        // child3 is half done. This means the parent is (half of 1/3 done) * 3.
+        child3.completedUnitCount = 5
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, ((1.0 / 3.0) / 2.0) * 3.0, accuracy: 0.01)
+        
+        // Finish child3
+        child3.completedUnitCount = 10
+        XCTAssertTrue(child3.isFinished)
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, (((1.0 / 3.0) / 2.0) * 2.0) + (1.0 / 3.0), accuracy: 0.01)
+        
+        // Finish child2
+        child2.completedUnitCount = 10;
+        XCTAssertTrue(child2.isFinished)
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, ((1.0 / 3.0) / 2.0) + ((1.0 / 3.0) * 2.0), accuracy: 0.01)
+        
+        // Finish child1
+        child1.completedUnitCount = 10;
+        XCTAssertTrue(child1.isFinished)
+        XCTAssertEqualWithAccuracy(parent.fractionCompleted, 1.0, accuracy: 0.01)
+        XCTAssertTrue(parent.isFinished)
+        XCTAssertEqual(parent.completedUnitCount, parent.totalUnitCount)
+
+    }
+    
+    func test_notReturningNaN() {
+        let p = Progress(parent: nil)
+        
+        let tests = [(-1, -1, true, 0.0),
+                     (0, -1, true, 0.0),
+                     (1, -1, true, 0.0),
+                     (-1, 0, true, 0.0),
+                     (0, 0, true, 0.0),
+                     (1, 0, false, 1.0),
+                     (-1, 1, true, 0.0),
+                     (0, 1, false, 0.0),
+                     (1, 1, false, 1.0)]
+        
+        for t in tests {
+            p.completedUnitCount = Int64(t.0)
+            p.totalUnitCount = Int64(t.1)
+            XCTAssertEqual(t.2, p.isIndeterminate, "failed with \(t)")
+            XCTAssertEqual(t.3, p.fractionCompleted,  "failed with \(t)")
+        }
+    }
+    
+    func test_handlers() {
+        let parent = Progress(parent: nil)
+        let parentSema = DispatchSemaphore(value: 0)
+        
+        let child = Progress(parent: nil)
+        let childSema = DispatchSemaphore(value: 0)
+        
+        parent.addChild(child, withPendingUnitCount: 1)
+        
+        parent.cancellationHandler = { parentSema.signal() }
+        child.cancellationHandler = { childSema.signal() }
+        parent.pausingHandler = { parentSema.signal() }
+        child.pausingHandler = { childSema.signal() }
+        parent.resumingHandler = { parentSema.signal() }
+        child.resumingHandler = { childSema.signal() }
+
+        parent.cancel()
+        XCTAssertEqual(.success, parentSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+        XCTAssertEqual(.success, childSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+        
+        parent.pause()
+        XCTAssertEqual(.success, parentSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+        XCTAssertEqual(.success, childSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+
+        parent.resume()
+        XCTAssertEqual(.success, parentSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+        XCTAssertEqual(.success, childSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+    }
+    
+    func test_alreadyCancelled() {
+        let parent = Progress(parent: nil)
+        let parentSema = DispatchSemaphore(value: 0)
+        let child = Progress(parent: nil)
+        let childSema = DispatchSemaphore(value: 0)
+        parent.addChild(child, withPendingUnitCount: 1)
+
+        parent.cancel()
+        
+        parent.cancellationHandler = { parentSema.signal() }
+        child.cancellationHandler = { childSema.signal() }
+        
+        XCTAssertEqual(.success, parentSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+        XCTAssertEqual(.success, childSema.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(3)))
+    }
+    
+    func test_userInfo() {
+        let p = Progress(parent: nil, userInfo: [.estimatedTimeRemainingKey : 1000])
+        XCTAssertEqual(p.userInfo[.estimatedTimeRemainingKey] as? Int, 1000)
+        
+        p.setUserInfoObject(2000, forKey: .fileTotalCountKey)
+        XCTAssertEqual(p.userInfo[.fileTotalCountKey] as? Int, 2000)
+
+        p.setUserInfoObject(nil, forKey: .fileTotalCountKey)
+        XCTAssertEqual(p.userInfo[.fileTotalCountKey] as? Int, nil)
+    }
+}
diff --git a/TestFoundation/main.swift b/TestFoundation/main.swift
index 0de1e0d..5e325c4 100644
--- a/TestFoundation/main.swift
+++ b/TestFoundation/main.swift
@@ -83,4 +83,6 @@
     testCase(TestNSMutableAttributedString.allTests),
     testCase(TestNSFileHandle.allTests),
     testCase(TestUnitConverter.allTests),
+    testCase(TestProgressFraction.allTests),
+    testCase(TestProgress.allTests),
 ])
diff --git a/build.py b/build.py
index 2a722f7..293cf11 100644
--- a/build.py
+++ b/build.py
@@ -364,7 +364,8 @@
 	'Foundation/NSPortMessage.swift',
 	'Foundation/NSPredicate.swift',
 	'Foundation/NSProcessInfo.swift',
-	'Foundation/NSProgress.swift',
+	'Foundation/Progress.swift',
+	'Foundation/ProgressFraction.swift',
 	'Foundation/NSPropertyList.swift',
 	'Foundation/NSRange.swift',
 	'Foundation/NSRegularExpression.swift',
@@ -473,6 +474,7 @@
 foundation_tests = SwiftExecutable('TestFoundation', [
 	'TestFoundation/main.swift',
         'TestFoundation/HTTPServer.swift',
+        'Foundation/ProgressFraction.swift',
 ] + glob.glob('./TestFoundation/Test*.swift')) # all TestSomething.swift are considered sources to the test project in the TestFoundation directory
 
 Configuration.current.extra_ld_flags = '-L'+Configuration.current.variables["LIBDISPATCH_BUILD_DIR"]+'/src/.libs'