func (t *TaskEngine) Get(taskId defs.Id) (defs.Task, error) {
	task, ok := t.taskMap.Get(taskId)

	if !ok {
		return defs.Task{}, apperror.New(errors.New("Task not found"), apperror.TaskNotFound)
	}

	return (*task), nil
}
func (t *TaskEngine) Poll(taskId defs.Id) (bool, error) {

	task, ok := t.taskMap.Get(taskId)

	if !ok {
		return false, apperror.New(errors.New("Task not found"), apperror.TaskNotFound)
	}

	if task.Claims == nil {
		return false, nil
	} else {
		return task.Claims[len(task.Claims)-1].Complete, nil
	}
}
func (t *TaskEngine) Claim(taskId defs.Id, holdingClaimId defs.Id, complete bool) (defs.Claim, error) {

	task, ok := t.taskMap.Get(taskId)
	if !ok {
		return defs.Claim{}, apperror.New(errors.New("Task not found"), apperror.TaskNotFound)
	}

	newClaim, err := t.ch.Claim(task, holdingClaimId, complete)
	if err != nil {
		return defs.Claim{}, err
	} else {
		return *newClaim, err
	}
}
func (t *TaskEngine) Stake(workerId defs.Id, namedq string) (defs.Task, defs.Claim, error) {

	// look for the next available task in namedq to be allocated to the worker
	q := t.qStore.GetQueue(namedq)
	task, ok := q.Deq()

	if !ok {
		return defs.Task{}, defs.Claim{}, apperror.New(errors.New("No task to allocate"), apperror.NoTaskToClaim)
	}

	// mark the task as allocated
	// the way we allocate a task is - when we create a cliam for it
	// if the claim expires, the task needs to go back to the priority queue to be reclaimed

	claim := t.ch.Stake(task, workerId)

	return *task, *claim, nil
}