/// <summary>
        /// Process activity task
        /// </summary>
        /// <param name="input">Input for the activity task</param>
        /// <returns>Processing result: either an updated SWF activity, or an error message</returns>
        private async Task <ProcessSwfActivityResult> ProcessTask(string input)
        {
            ProcessSwfActivityResult result = new ProcessSwfActivityResult();

            try
            {
                //read SWF activity info
                SwfActivity swfActivity = JsonSerializer.Deserialize <SwfActivity>(input);
                //based on SWF activity's info create an EMR activity
                SingleEmrActivityIterator singleEmrActivityIterator = new SingleEmrActivityIterator(swfActivity);

                //Run this activity on EMR Service
                using (EmrActivitiesRunner emrRunner = new EmrActivitiesRunner(this.EmrJobLogger, this.EmrJobStateChecker, this.EmrClient, this.Settings, singleEmrActivityIterator))
                {
                    emrRunner.JobFlowId = swfActivity.JobFlowId; //set JobFlowId for the current activity
                    bool emrJobOk = await emrRunner.Start();

                    if (emrJobOk)
                    {
                        swfActivity.JobFlowId = emrRunner.JobFlowId; //read JobFlowId in case it was changed (for example, during starting a new EMR job)
                        result.Output         = swfActivity;
                    }
                    else
                    {
                        result.ErrorMessage = emrRunner.ErrorMessage;
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
            }

            return(result);
        }
        protected async override void DoWorkSafe()
        {
            ActivityTask activityTask = await this.Poll();

            if (!String.IsNullOrEmpty(activityTask.TaskToken))
            {
                ProcessSwfActivityResult processResult = await ProcessTask(activityTask.Input);

                if (string.IsNullOrEmpty(processResult.ErrorMessage))
                {
                    await CompleteTask(activityTask.TaskToken, processResult.Output);
                }
                else
                {
                    await FailTask(activityTask.TaskToken, activityTask.Input, processResult.ErrorMessage);
                }
            }
        }