anchor.diff:      
       /// Processes a string input and returns the result
       abstract member Process     : string -> string
  +
  +// Represents a workflow
  +type IWorkflow = 
  +    inherit ISchedulable
  +
  +    abstract member TaskList                     : TaskList
  +    abstract member Version                      : string
  +    abstract member TaskStartToCloseTimeout      : Seconds option
  +    abstract member ExecutionStartToCloseTimeout : Seconds option
  +    abstract member ChildPolicy                  : ChildPolicy option
  +
  +    abstract member Start       : Amazon.SimpleWorkflow.AmazonSimpleWorkflowClient -> unit
  +
  +// #endregion
  +
  +type SchedulableState =
  +    {
  +        mutable StageNumber   : int
  +        mutable AttemptNumber : int
  +        mutable MaxAttempts   : int
  +        mutable ActionNumber  : int     // zero-based index of the action
  +        mutable TotalActions  : int     // total number of actions scheduled together
  +    }
  +
  +type Reducer = string[] -> string
  +
  +/// The different actions that can be taken as a stage in the workflow
  +type StageAction = 
  +    | ScheduleActivity      of IActivity
  +    | StartChildWorkflow    of IWorkflow
  +    // ParallelActions args :
  +    //      the list of ISchedulable actions to schedule
  +    //      reducer to aggregate results from all the scheduled actions into a single result
  +    | ParallelActions       of ISchedulable[] * Reducer
  +
  +/// Represents a stage in the workflow
  +type Stage =
  +    {
  +        StageNumber : int           // zero-based index, e.g. 5 = 6th stage
  +        Action      : StageAction   // what action to perform at this stage in the workflow?
  +    }
  +
  +type WorkflowState =
  +    {
  +        CurrentStageNumber  : int   // zero-based index of the currently executing stage
  +        TotalActions        : int   // total number of actions scheduled at this stage
  +        CompletedActions    : int   // the number of completed 
  +    }
  +
  +[<AutoOpen>]
  +module WorkflowUtils =
  +    let private schedulableStateSerializer = JsonSerializer<SchedulableState>()
  +    let private workflowSerializer         = JsonSerializer<WorkflowState>()
  +
  +    /// Serialize/Deserialize a SchedulableState to and from string
  +    let serializeSchedulableState   = schedulableStateSerializer.SerializeToString
  +    let deserializeSchedulableState = schedulableStateSerializer.DeserializeFromString
  +
  +    /// Serialize/Deserialize a WorkflowState to and from string
  +    let serializeWorkflowState      = workflowSerializer.SerializeToString
  +    let deserializeWorkflowState    = workflowSerializer.DeserializeFromString
  +
  +    /// Returns the scheduled action given the action's current state and the stage of workflow it's at
  +    let getScheduled state = function
  +        | { Action = ScheduleActivity(activity) }       -> activity :> ISchedulable
  +        | { Action = StartChildWorkflow(workflow) }     -> workflow :> ISchedulable
  +        | { Action = ParallelActions(schedulables, _) } -> schedulables.[state.ActionNumber]
  +
  +    /// Identifies the key events which we need to respond to
  +    let (|KeyEvent|_|) historyEvt = 
  +        match historyEvt with
  +        | { EventType = ActivityTaskFailed _ } 
  +        | { EventType = ActivityTaskTimedOut _ } 
  +        | { EventType = ActivityTaskCompleted _ }
  +        | { EventType = ChildWorkflowExecutionFailed _ } 
  +        | { EventType = ChildWorkflowExecutionCompleted _ } 
  +        | { EventType = ChildWorkflowExecutionCompleted _ }
  +        | { EventType = StartChildWorkflowExecutionInitiated _ }
  +        | { EventType = WorkflowExecutionStarted _ }
  +            -> Some historyEvt.EventType
  +        | _ -> None
  +
  +    /// Given an array of ISchedulable, returns the activities
  +    let getActivities (arr : ISchedulable[]) = arr |> Array.choose (function | :? IActivity as activity -> Some activity | _ -> None)
  +
  +    /// Given an array of ISchedulable, returns the workflows
  +    let getWorkflows (arr : ISchedulable[])  = arr |> Array.choose (function | :? IWorkflow as workflow -> Some workflow | _ -> None)
  +
  +    /// Formats the activity ID for an activity given its current state
  +    let getActionId actionName { StageNumber = stageNum; AttemptNumber = attempts; ActionNumber = actionNum } = 
  +        sprintf "%d.stag_%s.act_%d.attempt_%d" stageNum actionName actionNum attempts
  +
  +    /// Formats the activity version for an activity at a particular stage of a workflow
  +    let getActivityVersion workflowName stageNum = sprintf "%s.%d" workflowName stageNum
  +    
  +    /// Returns the event type associated with the specified event ID
  +    let findEventTypeById eventId (evts : HistoryEvent seq) =
  +        evts |> Seq.pick (function 
  +            | { EventId = eventId'; EventType = eventType } when eventId = eventId' 
  +                -> Some eventType 
  +            | _ -> None)
  +
  +    /// Returns the decision to schedule an activity
  +    let scheduleActivity actionNum totalActions workflowName stageNum (activity : IActivity) input attempts = 
  +        let activityType = ActivityType(Name = activity.Name, Version = getActivityVersion workflowName stageNum)
  +        let state        = { 
  +                                StageNumber   = stageNum
  +                                AttemptNumber = attempts + 1
  +                                MaxAttempts   = activity.MaxAttempts
  +                                ActionNumber  = actionNum
  +                                TotalActions  = totalActions
  +                            }
  +        let control      = serializeSchedulableState state
  +        let decision     = ScheduleActivityTask(getActionId activity.Name state, 
  +                                                activityType,
  +                                                Some activity.TaskList, 
  +                                                input,
  +                                                Some activity.TaskHeartbeatTimeout, 
  +                                                Some activity.TaskScheduleToStartTimeout, 
  +                                                Some activity.TaskStartToCloseTimeout, 
  +                                                Some activity.TaskScheduleToCloseTimeout,
  +                                                Some control)
  +        decision
  +
  +    /// Returns the decision to schedule a stage with a single activity
  +    let scheduleActivityStage = scheduleActivity 0 1
  +
  +    /// Returns the decision to schedule a child workflow
  +    let scheduleChildWorkflow actionNum totalActions stageNum (workflow : IWorkflow) input attempts =
  +            let schedulable  = workflow :> ISchedulable
  +            let workflowType = WorkflowType(Name = schedulable.Name, Version = workflow.Version)
  +            let state        = { 
  +                                    StageNumber   = stageNum
  +                                    AttemptNumber = attempts + 1
  +                                    MaxAttempts   = schedulable.MaxAttempts
  +                                    ActionNumber  = actionNum
  +                                    TotalActions  = totalActions
  +                               }
  +            let control      = serializeSchedulableState state
  +            let decision     = StartChildWorkflowExecution(getActionId schedulable.Name state, 
  +                                                           workflowType,
  +                                                           workflow.ChildPolicy,
  +                                                           Some workflow.TaskList, 
  +                                                           input,
  +                                                           None,
  +                                                           workflow.ExecutionStartToCloseTimeout,
  +                                                           workflow.TaskStartToCloseTimeout,                                                             
  +                                                           Some control)
  +            decision
  +
  +    /// Returns the decision to schedule a stage with a single child workflow
  +    let scheduleChildWorkflowStage = scheduleChildWorkflow 0 1
  +
  +// #region Activity Definition
   
   /// Represents an activity, which in essence, is a function that takes some input and 
   /// returns some output
  
positive.code: 
          | ChildWorkflowExecutionFailed(initiatedEvtId, _, workflowExec, _, details, reason) ->            
              let (StartChildWorkflowExecutionInitiated(_, _, _, _, _, _, input, control, _, _)) = findEventTypeById initiatedEvtId events
              failedStage control workflowExec.RunId input details reason
  
          | ChildWorkflowExecutionCompleted(initiatedEvtId, _, _, _, result) ->
              let (StartChildWorkflowExecutionInitiated(_, _, _, _, _, _, _, control, _, _)) = findEventTypeById initiatedEvtId events
  
negative.code:                  ?childPolicy             = childPolicy,
                   ?identity                = identity,
                   maxAttempts              = maxAttempts)         
                 
      // #region Public Events
  
      [<CLIEvent>] member this.OnDecisionTaskError = onDecisionTaskError.Publish
  