anchor.diff:              false
         else false
   
  -    // manual state machine instead of a task computation expression, this is visibly faster
  -    // But this is complex, TODO review, run benchmarks 
  +    // Manual state machine instead of a task computation expression, this is visibly faster
       let doMoveNextDiscreteTask(ct:CancellationToken) : Task<bool> =
  -      #if PRERELEASE
  -      Trace.Assert(this.HasValidState)
  -      #endif
         let mutable tcs = Runtime.CompilerServices.AsyncTaskMethodBuilder<bool>.Create() //new TaskCompletionSource<_>() //
         let returnTask = tcs.Task // NB! must access this property first
         let mutable firstStep = ref true
  
positive.code:     let continuous = cursors |> Array.map (fun x -> x.IsContinuous) 
      let isContinuous = continuous |> Array.forall id
  
      // indicates that previous move was OK and that a next move should not pre-build a state
      let mutable hasValidState = false
      // for ZipN, valid states are:
      // - all cursors are at the same key (virtually for continuous, they are at the next existing key)
      // - cursors are not at the same position but one of them returned false on move next/previous after 
      //   we tried to move from a valid state. In this state we could call MoveNextAsync or try to call Move Next repeatedly.
  
      // all keys where discrete cursors are positioned. they define where resulting keys are present
      let discreteKeysSet = SortedDeque(ZipNComparer(cmp))
      // active continuous cursors
  
negative.code:     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *)
  
  #nowarn "0086" // operator overloads are intentional, Series are as primitive as scalars, all arithmetic operations are defined on them as maps
  namespace Spreads
  
  open System
  