code: function iterator(state, tasks, callback)
  {
    var keys
      , tasksLeft = tasks.length
      , task      = tasks.shift()
      ;
  
    if (tasksLeft === 0)
    {
      return callback(null, state);
    }
  
    // init current task reference
    state._currentTask = {waiters: {}};
  
    if (typeOf(task) == 'object')
    {
      // update state with new options
      // to make it available for all the subcommands
      if (typeOf(task.options) == 'object')
      {
        state.options = extend(state.options || {}, task.options);
  
        // no need to process it further
        delete task.options;
      }
  
      // generate list of properties to update
      keys = Object.keys(task);
    }
  
    // convert non-array and non-object elements
    // into single element arrays
    if (typeof task != 'object')
    {
      task = [task];
    }
  
    execute(state, task, keys, function(err, modifiedState)
    {
      // reset current task
      // if it's error and modified state
      // isn't provided, use context
      (modifiedState || state)._currentTask = undefined; // eslint-disable-line no-undefined
  
      if (err) return callback(err);
  
      // proceed to the next element
      iterator(modifiedState, tasks, callback);
    });
  }
docs: Iterates over batch tasks with provided state object
  
  @private
  @param   {object} state - current state
  @param   {array} tasks - list of tasks to execute
  @param   {function} callback - invoked after all tasks have been processed
  @returns {void}