# HG changeset patch
# User cin
# Date 1479254768 -10800
# Node ID a867536c68fcc4555c214ab66b739df23965f3fd
# Parent  7d07503621fef9c681a883b986f5d8c717135874
Bound promise to CancellationToken
Added new states to ExecutionSate enum.
Added Safe.Guard() method to handle cleanup of the result of the promise
diff -r 7d07503621fe -r a867536c68fc Implab/Components/ExecutionState.cs
--- a/Implab/Components/ExecutionState.cs	Sun Nov 13 18:28:17 2016 +0300
+++ b/Implab/Components/ExecutionState.cs	Wed Nov 16 03:06:08 2016 +0300
@@ -13,6 +13,12 @@
 
         Running,
 
+        Suspending,
+
+        Suspended,
+
+        Resuming,
+
         Stopping,
 
         Failed,
diff -r 7d07503621fe -r a867536c68fc Implab/PromiseExtensions.cs
--- a/Implab/PromiseExtensions.cs	Sun Nov 13 18:28:17 2016 +0300
+++ b/Implab/PromiseExtensions.cs	Wed Nov 16 03:06:08 2016 +0300
@@ -180,8 +180,8 @@
         /// A callback used to cleanup already resolved promises in case of an error
         /// 
         public static IPromise PromiseAll(this ICollection> that, Action cleanup) {
-            Safe.ArgumentNotNull(that, "that");
-            
+            Safe.ArgumentNotNull(that, "that");
+
             int count = that.Count;
 
             if (count == 0)
@@ -263,6 +263,8 @@
 
         public static IPromise Then(this IPromise that, Func success, Func error, Func cancel) {
             Safe.ArgumentNotNull(that, "that");
+            Safe.ArgumentNotNull(success, "success");
+
             var d = new FuncTask(success, error, cancel, false);
             that.On(d.Resolve, d.Reject, d.CancelOperation);
             d.CancellationRequested(that.Cancel);
@@ -276,8 +278,8 @@
                     success(x);
                     return x;
                 },
-                error, 
-                cancel, 
+                error,
+                cancel,
                 false
             );
             that.On(d.Resolve, d.Reject, d.CancelOperation);
@@ -427,6 +429,13 @@
 
         #endregion
 
+        public static IPromise Guard(this IPromise that, Func, IPromise> continuation, Action cleanup) {
+            Safe.ArgumentNotNull(that, "that");
+            Safe.ArgumentNotNull(continuation, "continuation");
+            return continuation(that).Error((err) => {
+                that.On(cleanup);
+            }, true);
+        }
 
 #if NET_4_5
 
@@ -442,6 +451,24 @@
             return new PromiseAwaiter(that);
         }
 
+        public static IPromise BoundCancellationToken(this IPromise that, CancellationToken ct) {
+            Safe.ArgumentNotNull(that, "that");
+            ct.Register(that.Cancel);
+            return that.Then(null, null, (err) => {
+                ct.ThrowIfCancellationRequested();
+                throw new PromiseTransientException(err);
+            });
+        }
+
+        public static IPromise BoundCancellationToken(this IPromise that, CancellationToken ct) {
+            Safe.ArgumentNotNull(that, "that");
+            ct.Register(that.Cancel);
+            return that.Then(null, null, (err) => {
+                ct.ThrowIfCancellationRequested();
+                throw new PromiseTransientException(err);
+            });
+        }
+
 #endif
     }
 }
diff -r 7d07503621fe -r a867536c68fc Implab/Safe.cs
--- a/Implab/Safe.cs	Sun Nov 13 18:28:17 2016 +0300
+++ b/Implab/Safe.cs	Wed Nov 16 03:06:08 2016 +0300
@@ -127,5 +127,6 @@
                 return Promise.FromException(err);
             }
         }
+
     }
 }